본문 바로가기
study

[JSCODE] 1 : N 관계

by 당코 2023. 5. 31.

사용자, 게시물, 댓글 엔티티들 간에 서로 연관관계를 맺게 구조를 설계하여 기능을 추가하였다.

  • 사용자는 1개 이상의 게시글을 작성할 수 있다.
  • 게시글의 작성자는 1명뿐이다.
  • 1개의 게시글에는 1개 이상의 댓글이 달릴 수 있다.
  • 1개의 댓글은 1개의 게시글에만 달릴 수 있다.
  • 사용자는 1개 이상의 댓글을 작성할 수 있다.
  • 댓글의 작성자는 1명뿐이다.

 

게시글을 작성하거나 수정할 때 사용자를 인증하는 기능이 필요했다.

http header에 있는 token 정보를 이용하여 사용자의 아이디를 가져오는 방법도 있었지만

SecurityContextHolder에 저장되어 있는 인증 객체를 꺼내어 인증하는 방식을 선택하였다.

public static Long getCurrentMemberId(){
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if(authentication == null || authentication.getName() == null){
            throw new NoAuthorityInfoException();
        }

        return Long.parseLong(authentication.getName());
    }

 

특정 게시글 조회 기능

  • 특정 게시글에 달려있는 모든 댓글(댓글 내용, 댓글 작성 시간, 댓글 작성자의 이메일)을 같이 조회해라.

 

위와 같은 기능을 구현하기 위해서는 댓글, 게시글, 사용자의 정보가 모두 필요하다.

그렇기 때문에 DB에 접근할 때 쿼리를 최소한으로 날려 모든 정보를 가져오기 위해 fetch join을 사용하였다.

@Query("SELECT c FROM Comment c JOIN FETCH c.member m JOIN FETCH c.board b WHERE b = :board")
List<Comment> findAllByBoardAndMember(@Param("board") Board board);

 

일반 join

  • select 할 때 주체가 되는 엔티티만 영속화한다.
  • 만약 연관된 엔티티의 정보가 필요한 경우에는 다시 쿼리를 날려야 한다.

 

fetch join

  • select 할 때 주체가 되는 엔티티뿐만 아니라 연관된 엔티티를 모두 영속화한다.
  • FetchType이 Lazy인 엔티티를 참조하더라도 이미 영속성 컨텍스트에 올라와 있기 때문에 쿼리가 날아가지 않는다.

 

어려웠던 점, 개선할 점

무작정 기능만 작동하게 코드를 짜는 것은 비교적 어렵지 않았다. 하지만 조금이라도 빠르고 효율적으로 동작하는 코드를 만들기 위해 고민해야 할 것이 많았다. 조금은 오래 걸리더라도 안전성과 내가 정해놓은 기준에 맞게 코드를 짜도록 노력해야겠다.