Powolne ładowanie

Dostępny

1.1 Tło problemu

Kiedy zaczniesz pracować z prawdziwymi bazami danych, od razu przypomnisz sobie zdanie „Przedwczesna optymalizacja jest źródłem wszelkiego zła”. Dopiero teraz wspominasz ją w negatywny sposób. Podczas pracy z bazą danych optymalizacja jest niezbędna. I musisz z nim pracować już na etapie projektowania.

Hibernate sprawia, że ​​praca z bazą danych jest bardzo wygodna. Możesz łatwo uzyskać dowolne obiekty podrzędne, po prostu odpowiednio dodając adnotacje @OneToManyi pliki @ManyToMany. Przykład:

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

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

I jak łatwo jest uzyskać komentarze użytkownika:

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

I czeka cię wielka niespodzianka. Użytkownik ma kilka tysięcy komentarzy. Jeśli napiszesz taki kod, Hibernate oczywiście załaduje wszystkie komentarze użytkownika. Ale będzie to bardzo powolne, komentarze zajmą dużo pamięci i tak dalej.

Dlatego nie możesz tak pisać! W teorii tak, ale w praktyce nie.

1.2 Pogorszenie sytuacji dzięki kolekcjom

Problem jest jeszcze ciekawszy. W końcu zwykle nigdy nie potrzebujesz wszystkich komentarzy użytkownika. Nawet jeśli wyświetlasz je gdzieś na kliencie, wolisz robić to w częściach - stronach.

Potrzebujesz więc takich metod:

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

}

Pierwsza metoda zwraca tylko jedną stronę komentarzy - 50 sztuk. Druga metoda zwraca liczbę stron komentarzy. I to jest najgorsze. Aby po prostu sprawdzić liczbę komentarzy, trzeba było pobrać wszystkie komentarze z bazy danych!

1.3 Światełko na końcu tunelu

Dlatego nikt nie korzysta z naszych wspaniałych kolekcji dziecięcych. Nie, oczywiście są używane, ale tylko w ramach zapytań HQL. Na przykład tak:

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

}

Dobra wiadomość jest taka, że ​​możemy zaimplementować nasze metody w taki sposób, że nie musimy ładować dodatkowych danych z bazy danych. Zła wiadomość jest taka, że ​​nie jest łatwo pracować z naszymi kolekcjami.

Komentarze
  • Popularne
  • Najnowsze
  • Najstarsze
Musisz się zalogować, aby dodać komentarz
Ta strona nie ma jeszcze żadnych komentarzy