팀 빌딩 서비스를 만들면서 다음과 같은 요구 사항이 있었다.
사용자는 여러 팀에 속할 수 있다. 팀에는 여러 명의 사용자가 속할 수 있다.
이 간단한 요구 사항을 개발하기 위해 다음과 같이 진행했다. 참고로 JPA를 사용했다.
User, 팀은 Team이라 한다.User와 Team은 다대다 관계이다. 일대다—다대일 관계로 분리하기 위해 중간 테이블을 사용한다.Member라고 한다.Member는 중간 테이블에 대응된다. Member는 고유한 속성을 갖기 때문에 엔티티로 사용한다.User와 Member는 일대다 관계이고 Member와 Team은 다대일 관계이다.새로운 팀원을 등록할 때의 코드는 다음과 같다.
// userId와 teamId를 알고 있는 상황
User user = userRepository.findById(userId)
.orElseThrow(RuntimeException::new); // todo: create exception
Team team = teamRepository.findById(teamId)
.orElseThrow(RuntimeException::new); // todo: create exception
Member member = Member.builder()
.user(user)
.team(team)
.role(MEMBER) // 추가로 갖는 속성 값 예시
.build();
memberRepository.save(member);
Member를 저장, 조회, 수정, 삭제(CRUD)할 때 매번 User와 Team을 찾아야 했다. 따라서 매번 2번씩 select 쿼리가 나갔다. User와 Team에 관련된 도메인 로직이 있다면 상관 없지만, Member를 CRUD 하기 위한 용도로 매번 조회하는 것이 아쉬웠다. 그래서 방법이 없을까 고민을 해보았다.
우선 어떤 상황인지 살펴보자.