PrimeFaces Recursive Dynamic Tree


Merhaba,

Daha önce burada recursive fonksiyonunu anlatmaya çalıştım. PrimeFaces'te ağaç yapısı (Tree) kullanamayı recursive kullanarak oluşturmayı anlatmaya çalışacağım. Bunun için kullandıklarım

Netbeans 8.1
MySql 5.5.6
PrimeFaces 6.0
Maven

Bu işlem için öncelikle mysql de aşağıdaki script'i çalıştırarak kategoriler tablosunu oluşturuyoruz.

kategoriler_table
CREATE TABLE `kategoriler` (
  `kategori_id` int(11) NOT NULL AUTO_INCREMENT,
  `kategori_adi` varchar(45) DEFAULT NULL,
  `kategori_ust_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`kategori_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

kategoriler tablosunu oluşturulduktan sonra verileri aşağıdaki gibi giriyorum. Burada hangi kategorinin altında neyin olacağını kategori_ust_id kullanarak belirtiyoruz. Örneğin Windows, Linux, Mac kayıtlarının üst kategorisi olarak İşletim Sistemleri ne bağlı olduğunu ifade etmektedir.




Oluşturulan kategoriler tablosuna ait Entity Modelini aşağıdaki gibi oluşturuyoruz .

Kategoriler models

Kategoriler.java
package com.kurtomerfaruk.primefacesrecursivetree.models;

import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;

/**
 *
 * @author Omer Faruk KURT kurtomerfaruk@gmail.com
 * Created on date 24.12.2016 11:35:51
 */
@Entity
@Table(name = "kategoriler")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "Kategoriler.findAll", query = "SELECT k FROM Kategoriler k"),
    @NamedQuery(name = "Kategoriler.findByKategoriId", query = "SELECT k FROM Kategoriler k WHERE k.kategoriId = :kategoriId"),
    @NamedQuery(name = "Kategoriler.findByKategoriAdi", query = "SELECT k FROM Kategoriler k WHERE k.kategoriAdi = :kategoriAdi"),
    @NamedQuery(name = "Kategoriler.findByKategoriUstId", query = "SELECT k FROM Kategoriler k WHERE k.kategoriUstId = :kategoriUstId")})
public class Kategoriler implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "kategori_id")
    private Integer kategoriId;
    @Size(max = 45)
    @Column(name = "kategori_adi")
    private String kategoriAdi;
    @Column(name = "kategori_ust_id")
    private Integer kategoriUstId;

    public Kategoriler() {
    }

    public Kategoriler(Integer kategoriId) {
        this.kategoriId = kategoriId;
    }

    public Integer getKategoriId() {
        return kategoriId;
    }

    public void setKategoriId(Integer kategoriId) {
        this.kategoriId = kategoriId;
    }

    public String getKategoriAdi() {
        return kategoriAdi;
    }

    public void setKategoriAdi(String kategoriAdi) {
        this.kategoriAdi = kategoriAdi;
    }

    public Integer getKategoriUstId() {
        return kategoriUstId;
    }

    public void setKategoriUstId(Integer kategoriUstId) {
        this.kategoriUstId = kategoriUstId;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (kategoriId != null ? kategoriId.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Kategoriler)) {
            return false;
        }
        Kategoriler other = (Kategoriler) object;
        if ((this.kategoriId == null && other.kategoriId != null) || (this.kategoriId != null && !this.kategoriId.equals(other.kategoriId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "com.kurtomerfaruk.primefacesrecursivetree.models.Kategoriler[ kategoriId=" + kategoriId + " ]";
    }

}

Burada AbstractFacade tanımlıyoruz. Yani birden fazla service dosyası oluşturacak olursak bu sınıftan extend ederek bütün sınıflara ait ekle,güncelle,sil vb. gibi metodları yeniden yazmak yerine bir tane AbstractFacade classı oluşturup buradan genişletme yapmamız sistematik program yazma konusunda bize yardımcı olacaktır. Bunu classtan extend edilerek kendi service sınıflarımı oluşturuyoruz.

AbstractFacade.java
package com.kurtomerfaruk.primefacesrecursivetree.services;

import java.util.List;
import javax.persistence.EntityManager;

/**
 *
 * @author Omer Faruk KURT kurtomerfaruk@gmail.com
 * Created on date 24.12.2016 11:56:08
 */
public abstract class AbstractFacade<T> {

    private Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);
    }

    public void edit(T entity) {
        getEntityManager().merge(entity);
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }

    public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }

    public List<T> findRange(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        q.setMaxResults(range[1] - range[0] + 1);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    public int count() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
        cq.select(getEntityManager().getCriteriaBuilder().count(rt));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }

}



KategorilerFacade.java
package com.kurtomerfaruk.primefacesrecursivetree.services;

import com.kurtomerfaruk.primefacesrecursivetree.models.Kategoriler;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 *
 * @author Omer Faruk KURT kurtomerfaruk@gmail.com
 * Created on date 24.12.2016 11:56:08
 */
@Stateless
public class KategorilerFacade extends AbstractFacade<Kategoriler> {

    @PersistenceContext(unitName = "com.kurtomerfaruk_PrimeFacesRecursiveTree_war_1.0PU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public KategorilerFacade() {
        super(Kategoriler.class);
    }

}

Veritabanı ile bağlantı kurabilmek için aşağıdaki gibi bağlantı dosyamızı kullanıyoruz. Bunun için glassfish üzerinde bağlantı havuzu(connection pool ) oluşturmayı GlassFish Datasouce ve Connection Pool Ekleme GlassFish Datasouce ve Connection Pool Ekleme anlatmıştım. Buradaki java:app/jdbc/myDatasource GlassFish'te tanımlamış olduğumuz JDBC Datasource'ın adını ifade etmektedir.

persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="com.kurtomerfaruk_PrimeFacesRecursiveTree_war_1.0PU" transaction-type="JTA">
    <jta-data-source>java:app/jdbc/myDatasource</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties/>
  </persistence-unit>
</persistence>

Burada PrimeFaces'in tree bileşenini kullanarak tanımlıyoruz.

index.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form>
            <h3 style="margin-top:0">Single</h3>
            <p:tree value="#{nodeBean.root}" 
                    var="root" 
                    selectionMode="single"
                    selection="#{nodeBean.selectedNode}"
                    dynamic="true">
                <p:treeNode>
                    #{root}
                </p:treeNode>
            </p:tree>
        </h:form>
    </h:body>
</html>

Şimdi ise yukarıda tanımlamış olduğumuz tree için gerekli olan controller katmanını yazıyoruz.

NodeBean.java
package com.kurtomerfaruk.primefacesrecursivetree.controllers;

import com.kurtomerfaruk.primefacesrecursivetree.models.Kategoriler;
import com.kurtomerfaruk.primefacesrecursivetree.services.KategorilerFacade;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.inject.Inject;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;

/**
 *
 * @author Omer Faruk KURT kurtomerfaruk@gmail.com Created on date 24.12.2016
 * 11:43:30
 */
@ManagedBean
@ViewScoped
public class NodeBean implements java.io.Serializable {

    private static final long serialVersionUID = 7429631533180341314L;

    @Inject
    private KategorilerFacade service;

    private TreeNode root;
    private TreeNode selectedNode;
    private List<Kategoriler> liste;
    private List<Kategoriler> altListe;
    private List<Kategoriler> altListe2;

    public NodeBean() {
    }

    @PostConstruct
    public void init() {
        root = new DefaultTreeNode("Root", null);
        liste = new ArrayList<>();
        liste = service.findAll();
        recursive(liste, 0, root);
    }

    public TreeNode getRoot() {
        return root;
    }

    public void setRoot(TreeNode root) {
        this.root = root;
    }

    public TreeNode getSelectedNode() {
        return selectedNode;
    }

    public void setSelectedNode(TreeNode selectedNode) {
        this.selectedNode = selectedNode;
    }

    public List<Kategoriler> getListe() {
        return liste;
    }

    public void setListe(List<Kategoriler> liste) {
        this.liste = liste;
    }

    public List<Kategoriler> getAltListe() {
        return altListe;
    }

    public void setAltListe(List<Kategoriler> altListe) {
        this.altListe = altListe;
    }

    public List<Kategoriler> getAltListe2() {
        return altListe2;
    }

    public void setAltListe2(List<Kategoriler> altListe2) {
        this.altListe2 = altListe2;
    }

    public void recursive(List<Kategoriler> liste, int id, TreeNode node) {
        altListe2 = new ArrayList<Kategoriler>();
        altListe2 = altKategorileriGetir(id);
        for (Kategoriler k : altListe2) {
            TreeNode childNode = new DefaultTreeNode(k.getKategoriAdi(), node);
            recursive(altListe2, k.getKategoriId(), childNode);
        }
    }

    public List<Kategoriler> altKategorileriGetir(int i) {
        altListe = new ArrayList<Kategoriler>();
        for (Kategoriler k : getListe()) {
            if (k.getKategoriUstId() == i) {
                altListe.add(k);
            }
        }
        return altListe;
    }

}


Sonuç olarak



Sorunsuz javalı günler


Yorum Gönder

1 Yorumlar

  1. Merhabalar, bir zamanlar benim de yaptığım bir PF projesinde yaşadığım sıkıntılar sebebiyle sql taraflı çözüme ulaşmak için bazı girişim ve çözüm arayışlarım olmuştu ve şükür ki çözüme kavuştum. Sorunun çözümü ve mantığı anlamdında yardımcı olsun diye linkini paylaşmak isterim. İleride tekrar aramak istediğimizde komple çözüme ulaşabilir hale gelmiş olur.

    http://stackoverflow.com/questions/34773716/oracle-sql-hierarchical-queries

    YanıtlaSil