팀 빌딩 서비스를 만들면서 다음과 같은 요구 사항이 있었다.
사용자는 여러 팀에 속할 수 있다. 팀에는 여러 명의 사용자가 속할 수 있다.
이 간단한 요구 사항을 개발하기 위해 다음과 같이 진행했다. 참고로 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 하기 위한 용도로 매번 조회하는 것이 아쉬웠다. 그래서 방법이 없을까 고민을 해보았다.
우선 어떤 상황인지 살펴보자.