<인프런의 김영한님의 강의를 보고 정리한 내용입니다>
String query = "select t From Team t join fetch t.members m";
String query = "select t From Team t join fetch t.members m";
은 문제가 될 수 있지만,
String query = "select m From Member m join fetch m.team t";
는 다대일이기 때문에 페이징에 문제 없다.
페이징을 하기 위해서 다른 방법도 있는데, batch size를 이용하는 것이다.
public class JpaMain {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Team teamA = new Team();
teamA.setName("팀A");
em.persist(teamA);
Team teamB = new Team();
teamB.setName("팀B");
em.persist(teamB);
Member member1 = new Member();
member1.setUsername("회원1");
member1.setTeam(teamA);
em.persist(member1);
Member member2 = new Member();
member2.setUsername("회원2");
member2.setTeam(teamA);
em.persist(member2);
Member member3 = new Member();
member3.setUsername("회원3");
member3.setTeam(teamB);
em.persist(member3);
em.flush();
em.clear();
String query = "select t From Team t";
List<Team> result = em.createQuery(query, Team.class)
.setFirstResult(0)
.setMaxResults(2)
.getResultList();
for (Team team : result) {
System.out.println("team = " + team.getName() + "|members=" + team.getMembers().size());
}
tx.commit();
} catch (Exception e) {
tx.rollback();
e.printStackTrace();
} finally {
em.close();
}
emf.close();
}
}
이렇게 페이징 API를 쓴다고 하면, 현재는 LAZY 로딩이기에
프록시로 가져왔다가 for문 안에 들어올 때, 멤버에 대한 데이터를 들고오기에
팀을 select하고 멤버에 대한 쿼리가 따로 진행된다.
이 때, TEAM 엔티티에서 @BatchSize를 추가해준다.
@BatchSize(size = 100)
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
이렇게 하고 결과를 봐보면,
이렇게 멤버 쿼리가 하나만 실행됐다. 여기서
where
members0_.TEAM_ID in (
?, ?
)
이 부분의 ? 수 만큼의 팀을 조회한 것이다. 즉 batchSize 만큼 팀에 대한 쿼리를 넘기는 것.
이 BatchSize 설정은 엔티티 이외에도 persistence.xml에
<property name="hibernate.default_batch_fetch_size" value="100"/>
를 추가해서도 사용할 수 있다.
[ Spring ] DI 컨테이너와 싱글톤 (0) | 2022.02.04 |
---|---|
[ JPA ] Named Query (0) | 2022.02.03 |
[ JPA ] 페치 조인 (fetch join) - 기본 (0) | 2022.02.02 |
[ JPA ] JPQL 경로 표현식 (0) | 2022.01.31 |
[ JPA ] jpql 페이징 (0) | 2022.01.29 |