Lusta betöltés

Elérhető

1.1 A probléma háttere

Amikor valódi adatbázisokkal kezd dolgozni, azonnal eszébe jut a „korai optimalizálás minden rossz gyökere” kifejezés. Csak most negatívan emlékszel rá. Ha adatbázissal dolgozik, az optimalizálás elengedhetetlen. És már a tervezési szakaszban dolgozni kell vele.

A hibernálás nagyon kényelmessé teszi az adatbázissal való munkát. Könnyen megszerezhet bármilyen gyermekobjektumot, csak megfelelő megjegyzésekkel @OneToManyés @ManyToMany. Példa:

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

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

És milyen egyszerű megszerezni a felhasználók megjegyzéseit:

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

És nagy meglepetésben lesz részed. A felhasználónak több ezer megjegyzése van. Ha ilyen kódot ír, a Hibernate természetesen betölti a felhasználó összes megjegyzését. De nagyon lassú lesz, a megjegyzések sok memóriát foglalnak el és így tovább.

Ezért nem lehet így írni! Elméletben igen, de a gyakorlatban nem.

1.2 Tovább rontja a dolgokat gyűjteményekkel

A probléma még érdekesebb. Végül is, általában soha nem kell a felhasználó összes megjegyzése. Még ha megjeleníted is őket valahol a kliensen, inkább részenként - oldalakon - csinálod.

Tehát ilyen módszerekre van szükség:

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

}

Az első módszer csak egy oldalnyi megjegyzést ad vissza - 50 darabot. A második módszer a megjegyzések oldalainak számát adja vissza. És ez a legrosszabb. Ahhoz, hogy egyszerűen megtudja a hozzászólások számát, le kellett töltenie az összes megjegyzést az adatbázisból!

1.3 Fény az alagút végén

Ezért senki sem használja csodálatos gyermekgyűjteményeinket. Nem, természetesen használják, de csak a HQL lekérdezések részeként. Például így:

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

}

Jó hír, hogy módszereinket úgy tudjuk megvalósítani, hogy ne kelljen extra adatokat betöltenünk az adatbázisból. A rossz hír az, hogy nem könnyű dolgozni gyűjteményeinkkel.

Hozzászólások
  • Népszerű
  • Új
  • Régi
Hozzászólás írásához be kell jelentkeznie
Ennek az oldalnak még nincsenek megjegyzései