지연 로딩

사용 가능

1.1 문제의 배경

실제 데이터베이스로 작업을 시작하면 "성급한 최적화는 모든 악의 근원입니다."라는 문구를 즉시 기억할 것입니다. 이제야 그녀를 부정적인 방식으로 기억합니다. 데이터베이스로 작업할 때 최적화는 필수 불가결합니다. 그리고 이미 설계 단계에서 작업해야 합니다.

Hibernate는 데이터베이스 작업을 매우 편리하게 만듭니다. @OneToMany적절하게 주석을 달기 만 하면 자식 개체를 쉽게 가져올 수 있습니다 @ManyToMany. 예:

@Entity
@Table(name="user")
class User {
   @Column(name="id")
   public Integer id;

   @OneToMany(cascade = CascadeType.ALL)
   @JoinColumn(name = "user_id")
   public List<Comment> comments;
}

그리고 사용자의 의견을 얻는 것이 얼마나 쉬운지:

User user = session.get(User.class, 1);
List<Comment> comments = user.getComments();

그리고 당신은 큰 놀라움에 빠지게 될 것입니다. 사용자는 수천 개의 댓글을 가지고 있습니다. 이와 같은 코드를 작성하면 Hibernate는 물론 사용자의 모든 주석을 로드합니다. 그러나 그것은 매우 느릴 것이고 댓글은 많은 메모리를 차지할 것입니다.

그래서 그렇게 쓸 수 없습니다! 이론적으로는 그렇습니다. 하지만 실제로는 그렇지 않습니다.

1.2 컬렉션으로 상황 악화

문제는 훨씬 더 흥미 롭습니다. 결국 일반적으로 모든 사용자의 의견이 필요하지 않습니다. 클라이언트의 어딘가에 표시하더라도 페이지 단위로 표시하는 것을 선호합니다.

따라서 다음과 같은 방법이 필요합니다.

public class CommentsManager {
    private static final PAGE_SIZE = 50;

    public List<Comment> getCommentsPage(int userId, int pageIndex){
     	User user = session.get(User.class, userId);
     	List<Comment> comments = user.getComments();
     	return comments.subList(pageIndex * PAGE_SIZE, PAGE_SIZE);
    }

   public int getCommentsPageCount(int userId)   {
     	User user = session.get(User.class, userId);
     	List<Comment> comments = user.getComments();
     	return Math.ceil(  comments.size()/PAGE_SIZE);
   }

}

첫 번째 방법은 댓글 한 페이지(50개)만 반환합니다. 두 번째 메서드는 댓글 페이지 수를 반환합니다. 그리고 이것은 최악입니다. 단순히 댓글 수를 확인하려면 데이터베이스에서 모든 댓글을 다운로드해야 했습니다!

1.3 터널 끝의 빛

따라서 아무도 우리의 멋진 자식 컬렉션을 사용하지 않습니다. 아니요, 물론 사용되지만 HQL 쿼리의 일부로만 사용됩니다. 예를 들면 다음과 같습니다.

public class CommentsManager {
      private static final PAGE_SIZE = 50;

       public List<Comment> getCommentsPage(int userId, int pageIndex){
           	String hql = "select comments from User where id = :id";
           	Query<Comment> query = session.createQuery( hql, Comment.class);
           	query.setParametr("id", userId);
           	query.setOffset(pageIndex * PAGE_SIZE);
           	query.setLimit(PAGE_SIZE);
           	return query.list();
      }

      public int getCommentsPageCount(int userId)   {
           	String hql = "select count(comments) from User where id = :id";
           	Query<Integer> query = session.createQuery( hql, Integer.class);
           	query.setParametr("id", userId);
           	return Math.ceil(query.singleResult()/PAGE_SIZE);
     }

}

좋은 소식은 데이터베이스에서 추가 데이터를 로드할 필요가 없는 방식으로 메서드를 구현할 수 있다는 것입니다. 나쁜 소식은 컬렉션 작업이 쉽지 않다는 것입니다.

코멘트
  • 인기
  • 신규
  • 이전
코멘트를 남기려면 로그인 해야 합니다
이 페이지에는 아직 코멘트가 없습니다