2022 Masters Course/Web Backend Course

2022 마스터즈 코스(백엔드) 47일차 회고(2022. 3. 15.) - "그룹 리뷰의 즐거움"

ikjo 2022. 3. 15. 19:12

해당 글은 코드스쿼드 2022 마스터즈 코스 "Java 웹 백엔드" 과정을 수강하면서 학습한 내용 등에 대한 회고 글입니다. :)

 

수강 회고

CS10 과정에서는 하나의 미션에 대해 딱 한번의 그룹 리뷰만 있었고 일주일 중 총 2번의 그룹 리뷰가 있었다. 지금 진행되고 있는 웹 코스 과정에서는 해당 주의 미션에 대해 매주 화요일부터 목요일까지 총 3번의 그룹 리뷰가 진행되고 있다.앞선 회고에서도 여러번 언급했듯이 마스터즈 코스 과정을 하면서 유익하다고 생각되는 것들 중 하나는 "그룹 리뷰"시간이다.

 

그룹 리뷰 시간에는 주로 미션을 수행하면서 고민했었던 부분들이나 느낀 점들을 나누는 시간을 많이 갖는데, 자칫 나만의 생각에 갇혀 프로그래밍할 수도 있었던 것에 벗어날 수 있게 된다. 또한 내가 모르고 있는 것들을 소모임원들로부터 알게 되는 것도 좋지만, 내가 아는 것을 누군가와 공유함으로써 나 스스로가 더 잘 이해될 수 있게 되는 것도 큰 유익함이다. 아울러 내가 고민했었던 것을 상대도 고민하고 있었다는 것을 알 때 서로 공감할 수 있는 것도 하나의 장점인 것 같다.

 

백엔드 웹 코스 과정도 이제 2~3주밖에 남지 않았다. 그 이후에는 FE, 모바일 클래스 수강생분들과 12주간의 프로젝트 과정으로서 다른 경험을 할 수 있겠지만, 개인적으로 의미있고 유익했었던 그룹 리뷰를 잘 활용하기 위해 남은 과정간 그룹 리뷰에 좀 더 적극적으로 참여해야겠다는 생각이 들었다.

 

 

학습 회고

  • 스프링 부트 관련 미션 과제 풀이
    • Java 웹 백엔드 클래스 내 소모임원과 zoom 회의실에서 학습

 

INSERT + UPDATE = UPSERT?

내가 만들고 있는 스프링 부트 웹 앱에서는 사용자가 "회원가입"을 할 수 있고 회원가입 했을 때 저장된 "사용자 정보를 수정"할 수 있는 기능이 있다. 이때 레파지토리 단에 save라는 하나의 메서드 내에서 회원가입과 사용자 정보 수정을 구분하여 처리해주고 있었는데, Spring JDBC Template를 사용하여 나타내면 다음과 같았었다.

 

    @Override
    public User save(User user) {
        User userInformation;
        try {
            userInformation = findByUserId(user.getUserId())
                .orElseThrow(() -> new NoSuchElementException("해당되는 ID가 없습니다."));
        } catch (NoSuchElementException e) {
            SqlParameterSource parameters = new BeanPropertySqlParameterSource(user);
            jdbcInsert.execute(parameters);
            return user;
        }

        userInformation.update(user);

        SqlParameterSource parameters = new BeanPropertySqlParameterSource(userInformation);
        jdbc.update(UPDATE_USER, parameters);

        return user;
    }

 

사용자가 회원가입을 요청하든 기존 사용자 정보 수정을 요청하든 사용자는 자신의 입력 정보가 담긴 User 객체를 save 메서드 파라미터로 전달하게 된다. 이때 save 메서드 단에서는 사용자 ID로 기존의 사용자 정보를 조회했을 때 존재하지 않는다면 이는 사용자가 회원가입을 요청하는 것으로 판단할 수 있고, 존재한다면 사용자가 기존 정보에 대해 수정을 요청하는 것으로 판단할 수 있다. 이 과정에서 try-catch문(현재 코드) 외에도 사용자 ID로 사용자 정보 조회 시 null 체크를 통해 구분해줄 수 있다.

 

하지만 놀랍게도 SQL문에서는 이러한 상황을 예상(?)하고 유용한 키워드를 제시하고 있는데 MySQL 기준으로는 ON DUPLICATE KEY UPDATE 키워드이다. 이를 활용한다면 다음과 같이 코드를 개선할 수 있다.

 

    @Override
    public User save(User user) {
        SqlParameterSource parameters = new BeanPropertySqlParameterSource(user);
        jdbc.update("INSERT INTO user VALUES (:userId, :password, :name, :email) ON DUPLICATE KEY UPDATE name = :name, email = :email", parameters);

        return user;
    }

 

훨씬 간결해진 것을 확인할 수 있다. 우선 SQL문을 들여다 보면 가장 처음에는 INSERT를 통해 사용자 정보 데이터를 user 테이블에 주입하고 있다. 이때 뒤에 나오는 ON DUPLICATE KEY UPDATE가 중요한데, 이는 기존의 프라이머리 키(Primary Key)나 유니크 키(Unique Key)가 기존 user 테이블에 존재하고 있다면 뒤에 UPDATE문을 통해 특정 칼럼의 값들만 수정하겠다는 의미이다.(여기서는 name과 email에 대한 칼럼 값만 수정하고 있다.)

 

하지만 ON DUPLICATE KEY UPDATE 키워드는 MySQL에서는 적용되지만 h2 데이터 베이스를 사용한다면 이 키워드를 사용할 수 없다. 하지만 h2에서는 MERGE INTO ~ KEY 키워드를 제공하고 있다. 위와 동일한 기능을 이를 활용하여 코드로 나타내면 다음과 같다.

 

    @Override
    public User save(User user) {
        SqlParameterSource parameters = new BeanPropertySqlParameterSource(user);
        jdbc.update("MERGE INTO user KEY (user_id) VALUES (:userId, :password, :name, :email)", parameters);

        return user;
    }

 

개인적으로 MySQL SQL 보다 좀 더 직관적이고 이해하기 쉬웠다. 하지만 h2 데이터 베이스를 사용할 때는 이 코드를 사용하고 MySQL 데이터 베이스를 사용할 때는 다른 코드를 사용하는 것은 번거로운 일이고 호환성이 떨어지므로 h2 데이터 베이스를 MySQL 모드로 사용하여 ON DUPLICATE KEY UPDATE 키워드를 사용할 수도 있다.

 

 

좋았던 점

  • 이번 주에 함께 하게 된 소모임원분들과 오늘 첫 그룹 리뷰를 했는데, 그 과정에서 많은 것을 배우기도 했고, 부족하게나마 스스로 알고있는 지식을 공유할 수 있어서 좋았습니다.

 

 

아쉬웠던 점

  • 어제 오늘 과자를 많이 먹어서 다소 속이 안 좋은데, 식단(건강) 관리에 부주의 했었던 점이 아쉽습니다.. 😥

 

 

이전 보다 개선되었던 점

  • 코드 리뷰를 받다 보니 예전에는 그냥 무심코 사용했었던 코드나 방법들에 대해 스스로 점검("이 방법 말고 더 효율적인 방법이 없을까?" 등)할 수 있는 안목이 생겼습니다.