PrimeFaces DataTable Lazy özelliğini Hibernate ile Nasıl Kullanabiliriz? (Sayfalama, Filtreleme, Sıralama)

Bir jsf çatısı olan PrimeFaces kütüphanesi içerisinde yer alan datatable bileşenini, verileri listelemek için kullanıyoruz. Fakat büyük veriler sözkonusu olduğunda bu bileşeni standart haliyle kullanmamız durumunda çeşitli performans sorunlarıyla karşılabiliriz. Böylesi bir durumda uygulama sunucularında önemli hafıza kullanımına sebep olacak ve sistemi zorlayacaktır.

Bildiğiniz gibi frontend javascript kütüphanelerinde genel olarak şöyle bir yaklaşım vardır. İki türlü sayfalama (paging) vardır: Sunucu tarafında sayfalama (Server Side Paging) ve İstemci tarafında sayfalama (Client Side Paging). Veriler çok fazla ise sayfalama işleminin istemci tarafına gelmeden veritabanında yapılması kaynak kullanımı ve performans açısından en uygunu olacaktır. İstemci tarafında sayfalamanın küçük boyutlu veriler için uygun olabileceğini düşünebiliriz.

PrimeFaces, datatable bileşeninde standart, varsayılan hali ile melez bir yaklaşım benimsemiş gibi görünüyor. Veriler veritabanından veya başka bir kaynaktan uygulama sunucusuna toplu olarak getiriliyor, bu noktadan istemci tarafına ise sayfa başına düşen kayıt sayısı kadar kayıt dönmektedir. Bu yaklaşımında sakıncaları olacaktır. Büyük boyutlu veriler sözkonusu olduğunda ve hibernate gibi bir orm kullanılırsa fazla hafıza kullanımı ve Select N+1 gibi orm ile ilgili genel sorunlarla karşılaşmamız mümkün görünmektedir.

PrimeFaces bu konuyla ilgili lazy çözümünü önermektedir ki düşünceme göre standart olması gereken yöntem de bu olmalıdır.

Lazy kullanımına yönelik basit bir örnek yaparak nasıl kullanıldığına göz atmış olalım:

Index.xhtml
---
<h:form id="form">
    <p:dataTable var="person" value="#{personBean.lazyModel}" paginator="true" rows="10"
                 paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
                 rowsPerPageTemplate="5,10,15" id="personTable" lazy="true">        
        <p:column headerText="Id" sortBy="#{person.id}" filterBy="#{person.id}">
            <h:outputText value="#{person.id}" />
        </p:column>
        <p:column headerText="Name" sortBy="#{person.name}" filterBy="#{person.name}">
            <h:outputText value="#{person.Name}" />
        </p:column>
        <p:column headerText="Surname" sortBy="#{person.surname}" filterBy="#{person.Surname}">
            <h:outputText value="#{person.surname}" />
        </p:column>
        <p:column headerText="Age" sortBy="#{person.age}" filterBy="#{person.age}">
            <h:outputText value="#{person.age}" />
        </p:column>
    </p:dataTable>
</h:form>
---
PersonBean.java
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;

@ManagedBean(name="personBean")
@ViewScoped
public class PersonBean implements Serializable {
     
    private LazyDataModel<Person> lazyModel;
     
    public LazyDataModel<Person> getLazyModel() {
        return lazyModel;
    }

    public void setLazyModel(LazyDataModel<Person> lazyModel) {
        this.lazyModel = lazyModel;
    }

    // HibernateManager servisi ile ilgili işlemler yapılıyor

    -----

    @PostConstruct
    public void init(Boolean value) {
        lazyModel = new LazyDataModel<Person>() {
            @Override
            public Object getRowKey(Person object) {
                return object.getId();
            }

            @Override
            public List<Person> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {

                //******* Toplam Kayıt Sayısı bulunuyor **************
                String queryCountStmt = "select count(*) Person";

                if (filters.size() > 0) {
                    String whereHql = " where ";

                    for(Map.Entry<String, String> entry : filters.entrySet()) {
                        String key = entry.getKey();
                        String value = entry.getValue();

                        whereHql += " " + key + " like '" + value + "%'";
                    }

                    queryCountStmt += whereHql;
                }

                session = HibernateManager.GetHibernateSession();

                Query queryCount = session.createQuery(queryCountStmt);

                Long rowCount = queryCount.uniqueResult();

                lazyModel.setRowCount(rowCount.intValue());
                //******* Toplam Kayıt Sayısı bulundu **************

                //**** Kayıtlar Bulunuyor ****************

                String queryStmt = "from Person";

                if (filters.size() > 0) {
                    String whereHql = " where ";

                    for(Map.Entry<String, String> entry : filters.entrySet()) {
                        String key = entry.getKey();
                        String value = entry.getValue();

                        whereHql += " " + key + " like '" + value + "%'";
                    }

                    queryStmt += whereHql;
                }

                if (sortField != null) {

                    String sortOrderHql = "asc";

                    if (sortOrder.equals(SortOrder.DESCENDING)) {
                        sortOrderHql = "desc";
                    }

                    queryStmt += " order by " + sortField + " " + sortOrderHql;
                }

                Query query = session.createQuery(queryStmt);

                query.setFirstResult(first);

                query.setMaxResults(pageSize);

                List<Person> sonuclar = (List<Person>)query.list();

                return sonuclar;
            }
        };
    }
}
Person.java
import java.io.Serializable;

public class Person implements Serializable {    
    public String id;
    public String name;
    public String surname;
    public int age;
}

PersonBean.java sınıfında tanımlamış olduğumuz load metodu, her sayfaya erişmek istediğimizde otomatik olarak çağrılan kısım. Burda filtreleme, sıralama ve sayfalama ile ilgili parametrelere metodun içerisinden ulaşarak, gerekli hibernate kodlarını çağırabiliyoruz (query.setFirstResult(first) ve query.setMaxResults(pageSize);). Hibernate hql sözdizimine uygun yazdığımız kodu, yine criteria yapısına uygun bir şekilde de yazabiliriz.

 

 

Yorum Gönder

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Scroll to Top