본문 바로가기

Project

일정 관리 앱 프로젝트 트러블 슈팅 및 회고

https://github.com/bottle1000/calender_app_project

트러블 슈팅

1. 요청 데이터와 DTO 필드값 매핑, DB 컬럼과 LowMapper 매핑

  • 문제 상황 :요청 데이터를 받는 DTO와 응답 데이터로 반환하는 DTO를 작성하면서, DTO와 엔티티 간의 필드 매핑이 복잡해졌습니다. 특히 요청 데이터의 필드와 DB 컬럼의 관계를 정확하게 매핑해야 하는데, 이를 실수로 잘못 연결하는 문제가 발생했습니다. 또, calender 테이블과 author 테이블 간에 외래 키 관계를 설정하면서 아이디 충돌 문제가 발생하여 에러가 계속 발생했습니다.
    오류 메시지 : 
    (PreparedStatementCallback; Cannot add or update a child row: a foreign key constraint fails (calender.calender, CONSTRAINT fk_calendar_author FOREIGN KEY (author_id) REFERENCES author (id) ON DELETE CASCADE)] with root cause)
  • 해결 과정 : 요청 데이터에서 받은 값은 DTO 객체로 매핑하고, 그 후 DB에서 가져온 데이터를 Entity로 변환해야 했는데 특정 형식의 데이터가 DTO와 Entity 간에 일관되게 변환되는지 신경을 많이 써야 했습니다. 또, 테이블이 추가되면서 원래 있던 calendar 테이블의 id와 author 테이블의 id가 동일해져서 충돌 문제로 에러가 계속 발생 , 이를 일치시키기 위해 as키워드를 사용하여 쿼리 결과에서 컬럼명을 별칭으로 지정해주었습니다.
@Override
    public List<Calender> findById(Long id) {
        return jdbcTemplate.query("select c.id as calender_id, c.todo_list, c.password, c.created_at, c.updated_at, " +
                "a.id as author_id, a.name, a.email, a.created_at, a.updated_at " +
                "from calender c " +
                "join author a on c.author_id = a.id " +
                "where a.id = ?" , calenderRowMapper(), id);
    }
    
Author author = new Author(
                        rs.getLong("author_id"),
                        rs.getString("name"),
                        rs.getString("email"),
                        rs.getDate("created_at").toLocalDate(),
                        rs.getDate("updated_at").toLocalDate()
                );

                return new Calender(
                        rs.getLong("calender_id"),
                        rs.getString("todo_list"),
                        rs.getString("password"),
                        rs.getDate("created_at").toLocalDate(),
                        rs.getDate("updated_at").toLocalDate(),
                        author
                );

 

회고

1. 프로젝트 목표와 배운 점

  • 일단 목표는 프로젝트 초기에는 "필수 요구사항에 대해서 잘해보자!" 였지만 하다보니 욕심이 나기도 해서 도전 요구사항도 시도하게되었습니다. 그리고 그 과정 속에서 3-계층에 대해서 많이 배울 수 있었습니다.

2. 예상보다 어려웠던 부분과 개선할 부분

    • 이 부분은 쓸게 엄청나게 많은 것 같습니다 ㅎㅎ
      1. DB 와 SQL 쿼리
        • 어려웠던 점: SQL 쿼리를 처음 사용하다 보니, 쿼리를 짜는 것 자체가 매우 막막하게 느껴졌습니다. SQL의 문법이나 기본 개념에 익숙하지 않아 원하는 데이터를 어떻게 가져올지, 어떤 필드를 선택해야 할지 결정하는 데 시간이 많이 걸렸습니다. 특히 RowMapper()를 사용할 때, 쿼리에서 원하는 컬럼을 엔티티 필드명으로 잘못 매칭하는 실수를 자주 했습니다.
          SQL에 대한 기본적인 이해가 부족하고, 쿼리를 작성하면서 필드명과 컬럼명을 정확히 매칭하는 데 어려움이 있었습니다. 처음에는 실수도 많고, 실행 결과가 예상과 달라서 오류를 수정하는 데 많은 시간이 소요되었습니다.
      2. 페이징 구현
        • 어려웠던 점: 페이징 기능을 구현하려고 했을 때, 그 개념을 간단하게 생각했던 것과 달리 실제로 구현하면서 많은 어려움이 있었습니다. 특히 OFFSETLIMIT을 어떻게 적용해야 하는지, 데이터베이스에서 페이지를 나누는 방법에 대한 이해가 부족해 시작부터 막히는 부분이 많았습니다. 쿼리에서 이들을 어떻게 활용해야 할지 고민이 많았습니다.
      3. DTO 사용
        • 어려웠던 점: 이번 프로젝트에서 처음으로 DTO를 사용하면서, 요청과 응답을 관리하는 방식에 많은 어려움이 있었습니다. 기존에는 하나의 객체로 모든 데이터를 처리했지만, DTO를 분리하여 작성하면서 엔티티와 DTO 간의 관계가 복잡해지고, 생성자가 많아지는 문제에 직면했습니다.
          DTO의 역할과 설계에 대해 명확히 이해하지 못했기 때문에, 필요한 필드를 어떻게 구분해야 할지 고민이 많았습니다. 또한, 엔티티와 DTO 간의 변환 작업을 어떻게 효율적으로 처리할지 몰라서 복잡한 코드가 많아졌습니다.

3. 향후 개발에 대한 계획

  • 일단 DTO에 대해서 피드백을 받고 세분화 해보기.
  • DB와 SQL에 대해서 더 공부해서 리팩토링 및 기능 추가.
  • 클린한 API 설계하기.