지연 로딩

All lectures for KO purposes
레벨 1, 레슨 853
사용 가능

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);
     }
 
}

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

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION