- 게시판 프로젝트에서 홈을 요청하면 게시글 리스트를 불러온다. 문제는 쿼리인데, 페이징 할 때마다 쿼리가 3개가 나간다
- select 게시글
- select 회원: 닉네임 조회
- 게시글 count: 페이징 뷰게시판 프로젝트에서 홈 화면에서 게시글을 불러온다. 문제는 쿼리인데, 페이징 할 때마다 쿼리가 3개가 나간다.
- 김영한님의 JPA 강의에서 들은 fetch join을 적용해보려 한다.

fetch join
- 여러 엔티티를 한 번의 SQL로 가져오는 것이다.
- 내 상황에서는 게시글을 불러오고 회원을 불러왔는데 이제 한 번에 fetch join으로 가져온다는 것이다. 이렇게 되면 쿼리 한 번에 회원이 영속성 컨테스트에 처음부터 들어있기 때문에 성능 최적화에 좋다.
- JPQL과 나가는 SQL 쿼리는 이렇다.
- JPQL:
select p from Post p join fetch p.member;
- SQL:
select p.\*, m.\* from Post p inner join Member m on p.member\_id = m.id
- JPQL:
적용 전
@RequiredArgsConstructor
@Repository
public class PostRepository {
private final EntityManager em;
public Long save(Post post) {
em.persist(post);
return post.getId();
}
public Post findById(Long postId) {
return em.find(Post.class, postId);
}
public List<Post> findAll() {
return em.createQuery("select p from Post p", Post.class)
.getResultList();
}
public List<Post> findPage(int offset, int limit) {
return em.createQuery("select p from Post p order by p.createDate DESC", Post.class)
.setFirstResult(offset)
.setMaxResults(limit)
.getResultList();
}
public Long countPost() {
return em.createQuery("select count(p) from Post p", Long.class)
.getSingleResult();
}
public void delete(Post post) {
em.remove(post);
}
}
- 내 게시판에서는 게시글을 조회하는 곳이면 회원을 조회하게 되어있다. 그래서 쿼리가 2개씩 나가게 되는데 이를 fetch join을 사용하여 줄이려 한다.

적용 후
@RequiredArgsConstructor
@Repository
public class PostRepository {
private final EntityManager em;
public Long save(Post post) {
em.persist(post);
return post.getId();
}
public Optional<Post> findById(Long postId) {
return em.createQuery("select p from Post p" +
" join fetch p.member where p.id = :postId", Post.class)
.setParameter("postId", postId)
.getResultList().stream().findFirst();
}
public List<Post> findAll() {
return em.createQuery("select p from Post p", Post.class)
.getResultList();
}
public List<Post> findPage(int offset, int limit) {
return em.createQuery("select p from Post p" +
" join fetch p.member " +
" order by p.createDate DESC", Post.class)
.setFirstResult(offset)
.setMaxResults(limit)
.getResultList();
}
public Long countPost() {
return em.createQuery("select count(p) from Post p", Long.class)
.getSingleResult();
}
public void delete(Post post) {
em.remove(post);
}
}
select p from Post p join fetch p.member
를 이용해 게시글을 가져올 때 한 번에 쿼리로 회원의 엔티티까지 가져오게 되었다.
Hibernate: select p1_0.post_id,p1_0.category,p1_0.content,p1_0.create_date,m1_0.member_id,m1_0.email,m1_0.join_date,m1_0.join_root,m1_0.password,m1_0.role,m1_0.user_name,p1_0.title from posts p1_0 join member m1_0 on m1_0.member_id=p1_0.member_id where p1_0.post_id=?
'Spring > JPA' 카테고리의 다른 글
[JPA] Hibernate 6.1 @OneToMany 일대다 조회 시 DISTINCT 자동 적용 (1) | 2023.01.25 |
---|
댓글