주노 님의 블로그

20240813 본캠프 22일차 TIL 본문

TIL

20240813 본캠프 22일차 TIL

juno0432 2024. 8. 14. 00:16

본캠프 22일차 내용 간단요약

  • 09:00 ~ 10:00 : 코드카타
  • 10:00 ~ 10:10 : 팀 회의
  • 10:10 ~ 12:00 : 강의
    2주차 1강 ~ 2주차 4강
  • 12:00 ~ 13:00 : 점심시간
  • 13:00 ~ 18:00 : 개인 과제 구현
  • 18:00 ~ 19:00 : 저녁시간
  • 19:00 ~ 20:00 : 개인 과제 구현
  • 20:00 ~ 21:00 : TIL작성 

오늘 해야할 일✔️ 🔺 ❌

✔️ SPRING 1주차 강의

🔺 필수 요구사항 구현

진짜 강의 1주차 내용을 내걸로 만들 기회잖앙?!

 


코드카타 - 숫자 짝꿍

더보기

옹알이의 문제가 너무 어려워서 (이해가) 넘어갔는데

굉장히 내가 복잡하고 이상하게 이해하고 있던거시었다..

 

나는 모든 글자를 조합해서 만드는건줄알고 왜 result가 이렇게 나왔지...

막 이생각 저생각했는데

아뉘었구.. 내일 풀어봐야지

 

숫자 짝꿍

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

대충 문제는
숫자로 이루어진 문자열 x와 y가 있는데

두 문자열중 겹치는 숫자만 가져오면 된다

 

대충 머릿속에서 그려지는 솔루션은

배열에다가 해당 숫자의 카운트를 한다음

역순으로 뱉어내면 될것이라고 생각했다

 

import java.util.*;

class Solution {
    public String solution(String X, String Y) {
        String answer = "";
        int [] xArr = new int [10];
        int [] yArr = new int [10];
        
        for(int i = 0; i <X.length(); i++)
        {
            int num = X.charAt(i)-'0';
            xArr[num]++;
        }
        for(int i = 0; i <Y.length(); i++)
        {
            int num = Y.charAt(i)-'0';
            yArr[num]++;
        }

        StringBuilder sb = new StringBuilder();
        
        for(int i = 9 ; i >= 0; i--)
        {
            int minResult = Math.min(xArr[i],yArr[i]);
            for(int j = 0; j<minResult; j++)
            {
                sb.append(i);
            }
        }

        answer = sb.toString();
        if(answer.isEmpty())
        {
            answer="-1";
        }
        
        boolean isZero = true;
        
        for(int i = 0; i < answer.length(); i++)
        {
            if(answer.charAt(i)!='0')
                isZero=false;
        }
        if(isZero==true)
        {
            return answer="0";
        }
        return answer;
    }
}

 

최종은 위 코드지만

 

짝꿍은 상당히 큰 정수일 수 있으므로, 문자열로 반환합니다.

라는 문구를 못보고 if(Integer.parseInt(answer)) ~ 을 했을때 런타임 에러가 뜨는것이다

 

코드를 봤을때는 for문이그렇게깊게들어가는게없는디..싶었다

짝꿍이 상당히 큰 정수라 parseInt로 해서 저런문제가..!

Long보다도 더 큰 범위라서 for문을 돌아 모든 char가 0이라면 0으로 반환해주는 방법을 사용하였다

 


강의

더보기

3 Layer Architecture

  • Controller, Service, Repository 세개의 계층으로 나뉘게 된다
  • Controller
    클라이언트의 요청을 받고, 응답데이터를 클라이언트에 전송하는 부분이다.
    Request 데이터가 있다면 Service에 전달한다

  • Service
    사용자의 비즈니스 로직을 처리하는 부분이다
    db의 접근이 필요할때는 Repository에게 요청한다

  • Repositroy
    db관리 (연결, 해제, 자원관리)를 하는 부분이다

기존 memo코드에서 service와 controller를 구분해보기

  •   기존의 controller이다.

    여기서 MemoService를 만들어 controller를 줄여보자.

    @PostMapping("/memos")
    public MemoResponseDto createMemo(@RequestBody MemoRequestDto requestDto) {
        MemoService memoService = new MemoService(jdbcTemplate);
        return memoService.createMemo(requestDto);
    }

    메모 생성 로직은 위와같이 작동할것이다
    controller은 말 그대로 데이터만 전달해주는 역할을 준수해준다

    public MemoResponseDto createMemo(MemoRequestDto requestDto)
    {
        // RequestDto -> Entity
        Memo memo = new Memo(requestDto);
    
        // DB 저장
        KeyHolder keyHolder = new GeneratedKeyHolder(); // 기본 키를 반환받기 위한 객체
    
        String sql = "INSERT INTO memo (username, contents) VALUES (?, ?)";
        jdbcTemplate.update( con -> {
                    PreparedStatement preparedStatement = con.prepareStatement(sql,
                            Statement.RETURN_GENERATED_KEYS);
    
                    preparedStatement.setString(1, memo.getUsername());
                    preparedStatement.setString(2, memo.getContents());
                    return preparedStatement;
                },
                keyHolder);
    
        // DB Insert 후 받아온 기본키 확인
        Long id = keyHolder.getKey().longValue();
        memo.setId(id);
    
        // Entity -> ResponseDto
        MemoResponseDto memoResponseDto = new MemoResponseDto(memo);
    
        return memoResponseDto;
    }

    memoService의 로직은 클라이언트의 값을 불러왔다고 보면된다
    아직은 repository가 만들어지지않아 db접근부분이 같이있지만
    repository를 만들어보자
    public MemoResponseDto createMemo(MemoRequestDto requestDto)
    {
        // RequestDto -> Entity
        Memo memo = new Memo(requestDto);
    
        // DB 저장
        MemoRepository memoRepository = new MemoRepository(jdbcTemplate);
        Memo saveMemo = memoRepository.save(memo);
    
        // Entity -> ResponseDto
        MemoResponseDto memoResponseDto = new MemoResponseDto(memo);
    
        return memoResponseDto;
    }

    service에서 데이터베이스 접근 관련 코드를 모두 repository로 옮긴다

    public Memo save(Memo memo)
    {
        KeyHolder keyHolder = new GeneratedKeyHolder(); // 기본 키를 반환받기 위한 객체
    
        String sql = "INSERT INTO memo (username, contents) VALUES (?, ?)";
        jdbcTemplate.update( con -> {
                    PreparedStatement preparedStatement = con.prepareStatement(sql,
                            Statement.RETURN_GENERATED_KEYS);
    
                    preparedStatement.setString(1, memo.getUsername());
                    preparedStatement.setString(2, memo.getContents());
                    return preparedStatement;
                },
                keyHolder);
    
        // DB Insert 후 받아온 기본키 확인
        Long id = keyHolder.getKey().longValue();
        memo.setId(id);
    
        return memo;
    }

    위 코드처럼 구현하면된다

    요약하자면
    controller에선 사용자의 입력을 받아 dto로 전달받고,
    service에선 받아온 dto를 db에 등록해주기 위해 repository로 던진다
    repository에서는 db접근을위해 jdbc템플릿을 사용하여 쿼리를 날려주는 역할이고
    그 값을 다시 service에 전달해주고 service는 다시 controller에 전달해주어 클라이언트로 전달해준다

개인 과제 구현

더보기

1-1 개인과제 구현

 

 먼저 저번주 금요일에 분석한 내용으로 만든 자료로 controller를 만들면 될거같고

 

 

erd 설계대로 엔티티클래스를 만들어서 이리저리 휘적휘적 하면될거같다

 

스프링 구현은 처음이라 일단 강의자료를 따라 하기로 했다

dto두개가 맞을까?

학교에서 썼을때는 하나로도 끝낸거같은데.. 일단.. 강의자료대로 따라해서 만들었다

 

조건 1

할일 담당자명 비밀번호 작성/수정일을 저장할수있다.

기간정보는 날짜와 시간을 모두 포함한다.

각 일정의 고유 식별자를 자동으로 생성하여 관리한다

최초 입력간에는 수정일은 작성일과 동일하다

등록된 일정의 정보를 반호나 받아 확인 할 수 있다

 

create table schedule
(
    scheduleId   bigint auto_increment
        primary key,
    contents     varchar(200)                         not null,
    password     varchar(100)                         not null,
    regDate      timestamp  default CURRENT_TIMESTAMP null,
    modDate      timestamp  default CURRENT_TIMESTAMP null,
    deleteStatus tinyint(1) default 0                 null,
    manager    varchar(200)                               not null,
);

 shcedule는 auto_increcement로 자동 증가하게 하며, primary key로 지정해 고유한 식별자가 되게했다

regDate는 defalut값으로 현재 시간으로 채워줬다

 

삭제보다는 soft-delete로 구현을하여 deleteStatus를 boolean값으로 놓아 삭제인지 아닌지 구분했다.

 

ScheduleController

    @PostMapping("/register")
    public ScheduleResponseDto createSchedule(@RequestBody ScheduleRequestDto scheduleRequestDto)
    {
        ScheduleService scheduleService = new ScheduleService(jdbcTemplate);
        return scheduleService.createSchedule(scheduleRequestDto);
    }

컨트롤러에는 /register 엔드포인트에 대한 post요청을 받는다

이때 입력된 값은 body에 담겨서 전달받는다.

입력된 값을 dto객체에 담아 서비스에 전달해준다 

 

ScheduleService 

    public ScheduleResponseDto createSchedule(ScheduleRequestDto scheduleRequestDto)
    {
        //dto > entity
        Schedule schedule = new Schedule(scheduleRequestDto);

        //db저장
        ScheduleRepository scheduleRepository = new ScheduleRepository(jdbcTemplate);
        Schedule saveSchedule = scheduleRepository.save(schedule);

        //Entity -> Re
        ScheduleResponseDto  responseDto = new ScheduleResponseDto(schedule);

        return responseDto;
    }

서비스는 레파지토리를 호출해서 db에 접근을하고, 컨트롤러에 결과데이터를 반환해준다

 

public Schedule save(Schedule schedule)
{
    KeyHolder keyHolder = new GeneratedKeyHolder(); // 기본 키를 반환받기 위한 객체

    String sql = "INSERT INTO schedule (contents, password, managerId) VALUES (?, ?, ?)";
    jdbcTemplate.update(con -> {
                PreparedStatement preparedStatement = con.prepareStatement(sql,
                        Statement.RETURN_GENERATED_KEYS);

                preparedStatement.setString(1, schedule.getContents());
                preparedStatement.setString(2, schedule.getPassword());
                preparedStatement.setLong(3, schedule.getManagerId());
                return preparedStatement;
            },
            keyHolder);

    Long id = keyHolder.getKey().longValue();
    schedule.setScheduleId(id);

    return schedule;
}

save메서드는 쿼리를 날려 db에 정상적으로 저장을 한다

keyholder를 통해 자동으로 생성된 키를 객체를 저장한후 서비스에 반환해준다.

 

조건 2

 선택한 일정의 단건 정보를 조회 할 수 있습니다

일정의 고유 식별자를 사용하여 조회합니다

 

    @GetMapping("/read")
    public Schedule readSchedule(@RequestParam Long id)
    {
        ScheduleService scheduleService = new ScheduleService(jdbcTemplate);
        return scheduleService.findById(id);
    }

파라미터로 id값을 입력받아 그 일정을 조회한다

 

 

1-5까지 구현한다음 튜터님께 코드리뷰를 요청하도록 하자..!

 

 

'TIL' 카테고리의 다른 글

20240815 본캠프 24일차 TIL  (0) 2024.08.15
20240814 본캠프 23일차 TIL  (0) 2024.08.14
20240812 본캠프 21일차 TIL  (0) 2024.08.12
20240809 본캠프 20일차 TIL  (0) 2024.08.09
20240808 본캠프 19일차 TIL  (0) 2024.08.08