프로젝트를 진행할 때 쿼리를 하나하나 살펴보는 편인데... 문뜩 의문점 발견했습니당
member entity가 team을 가진다고 하면,
findByTeamId와 findByTeam 쿼리가 다르게 나가는 것을 알았습니다..!
teamId로 찾을땐 left outer join을 하길래 무슨 차이일지, 실무에서는 어떤 것을 더 많이 사용하는지 궁금했습니다.
이 차이를 언급하며 내 인프런 교수님 영한님께 여쭤봤을땐
이 대답을 들었고 저 강의를 참고하면
// findByTeam
Team team = em.find(Team.class, 1L);
String qlString = "select m from Member m where m.team = :team";
List resultList = em.createQuery(qlString)
.setParameter("team", team)
.getResultList();
// findByTeamId
Team team = em.find(Team.class, 1L);
String qlString = "select m from Member m where m.team.id = :teamId";
List resultList = em.createQuery(qlString)
.setParameter("teamId", team.getId())
.getResultList();
둘 다 select m.* from Member m where m.team_id = ? 쿼리가 실행될거라고 하셨습니다!
그래서 남기는 블로그.. !!! 내가 해보잣 하하
[Spring boot + Spring data JPA + MySQL]
@Entity
public class Event{
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(columnDefinition = "BINARY(16)")
private UUID id;
@Column(nullable = false)
private String name;
@ManyToOne(fetch = FetchType.LAZY, optional = true, cascade = CascadeType.ALL)
@JoinColumn(name = "member_id")
private Member member;
// builder 생략
}
@Entity
public class Member {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
@Column(columnDefinition = "BINARY(16)")
private UUID id;
@Column(nullable = false)
private String name;
// builder 생략
}
딱 아래와 같은 상황입니다!
JPA Repository는 여기!
public interface EventJpaRepository extends JpaRepository<Event, UUID> {
Event findByMemberId(UUID memberId);
Event findByMember(Member member);
}
[Test code]
public class EventTest {
@Autowired
EventJpaRepository eventJpaRepository;
@Autowired
MemberJpaRepository memberJpaRepository;
@Test
public void findTest(){
Member member = memberJpaRepository.save(
Member.builder()
.name("배지현")
.build()
);
Event event = eventJpaRepository.save(
Event.builder()
.name("신나는 여름 이벤트")
.member(member)
.build()
);
Event findByOrganizer = eventJpaRepository.findByMember(member); // 1번
Event findByOrganizerId = eventJpaRepository.findByMemberId(member.getId()); // 2번
}
}
결과
둘의 차이는 맨 끝에
1번 쿼리는 where
2번 쿼리는 left outer join을 하네욥
비교
1번(findByMember)은 member를 찾는 findMember 쿼리 1개 + findByMember로 event를 찾는 쿼리 1개를 날려줘야합니다. 대신 가독성이 좋고 1차캐시에 member가 이미 있다면 뒷 쿼리 하나만 날리면 되네요!
2번(findByMemberId)은 1번이 날려야하는 쿼리 2개를 1개로 퉁쳐줘서 DB 접근을 줄여준다는 장점이 있지만 가독성이 나쁩니다.
사실 아직도 실무에서는 뭘 쓰는지 잘 모르겠네요...
아는 분 댓글 부탁드려요 ..!!
속도 개선을 위해.. 저는 그때그때 알맞는 걸로 적용하겠습니다.. 오늘의 호기심 탐구 이상 끝!
'Spring boot > 스프링 데이터 JPA' 카테고리의 다른 글
[spring boot] 벌크성 수정 쿼리 (0) | 2022.01.25 |
---|---|
[spring boot] 페이징과 정렬 (0) | 2022.01.24 |
[spring boot] 반환 타입 (0) | 2022.01.21 |
[spring boot] @Query, 메서드 이름으로 생성, NamedQuery (0) | 2022.01.21 |