CodeGym/Java курс/All lectures for BG purposes/Мързеливо зареждане

Мързеливо зареждане

На разположение

1.1 Предистория на проблема

Когато започнете да работите с реални бази данни, веднага ще си спомните фразата „Преждевременната оптимизация е коренът на всяко зло“. Само сега си спомняш за нея по негативен начин. При работа с база данни оптимизацията е незаменима. И трябва да работите с него още на етапа на проектиране.

Hibernate прави работата с базата данни много удобна. Можете лесно да получите всяHowви дъщерни обекти само чрез правилно анотиране @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();

И ще ви очаква голяма изненада. Потребителят има няколко хиляди коментара. Ако напишете code по този начин, 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);
   }

}

Първият метод връща само една page с коментари - 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);
     }

}

Добрата новина е, че можем да приложим нашите методи по такъв начин, че да не се налага да зареждаме допълнителни данни от базата данни. Лошата новина е, че не е лесно да се работи с нашите колекции.

Коментари
  • Популярен
  • Нов
  • Стар
Трябва да сте влезли, за да оставите коментар
Тази страница все още няма коментари