如今,有幾個JSF框架為數據表提供現成的分頁,列排序器和其他功能。 今天,我們將使用Primefaces數據表。
通常,數據表會將顯示的列表和實體放在用戶http會話中。 增加用戶會話中的對象將直接影響服務器性能。 每個顯示數據表并在會話中保留列表的用戶將在服務器中分配越來越多的內存。
為了看起來真實,我們的文章將使用JPA和HSQLDB作為數據庫,并且將使用JPQL查詢數據。
在本文的結尾,您將找到下載源代碼的鏈接。
我們將使用:
- JSF 2.0 – JBoss 7實施
- JBoss 7.1 –本文的代碼應應用于所有服務器
- 日食靛藍
- JPA 2.0 – JBoss 7實施
- HSQLDB(2.2.8)– HSQL是一個內存數據庫,它將更易于運行。
- Primefaces 3.2
這篇文章不是關于好的開發實踐,也不是關于添加項目建模的類層。 我只是想展示如何在沒有會話托管bean的情況下進行分頁。
我們只有一個實體,即Player類。 下面是班級代碼:
package com.model;import java.io.Serializable;import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;@Entity
public class Player implements Serializable{private static final long serialVersionUID = 1L;@Id@GeneratedValue(strategy = GenerationType.AUTO)private int id;private String name;private int age;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic int hashCode() {return getId();}@Overridepublic boolean equals(Object obj) {if(obj instanceof Player){Player player = (Player) obj;return player.getId() == getId();}return false;}
}
我們將需要在“ src / META-INF”文件夾中創建一個persistence.xml文件:
<?xml version="1.0" encoding="UTF-8"?><persistence version="2.0"xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"><persistence-unit name="JSFPU" transaction-type="JTA"><jta-data-source>java:/JSFDS</jta-data-source><properties><property name="hibernate.show_sql" value="false" /><property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" /><property name="hibernate.connection.shutdown" value="true" /><property name="hibernate.hbm2ddl.auto" value="create-drop" /></properties></persistence-unit>
</persistence>
為了抽象數據庫事務,我們將使用一個名為MyTransaction的類:
package com.connection;import java.io.Serializable;import javax.persistence.EntityManager;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;public class MyTransaction implements Serializable {/****/private static final long serialVersionUID = 1L;private Connection connection = new Connection(); public void begin() throws NotSupportedException, SystemException {connection.begin();}public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException,SystemException {connection.commit();}public int getStatus() throws SystemException {return connection.getStatus();}public void rollback() throws IllegalStateException, SecurityException, SystemException {connection.rollback();}public void setRollbackOnly() throws IllegalStateException, SystemException {connection.setRollbackOnly();}public void setTransactionTimeout(int timeout) throws SystemException {connection.setTransactionTimeout(timeout);}public static MyTransaction getNewTransaction() {return new MyTransaction();}public EntityManager getEntityManager() {return connection.getEntityManager();}
}
您可以在上面的代碼中看到,該類只是數據庫連接的抽象; 它將幫助我們進行數據庫查詢。 您可以使用任何類型的連接,甚至可以使用EJB來避免這種手動連接管理。
檢查連接類代碼:
package com.connection;import java.io.Serializable;import javax.naming.Context;
import javax.naming.InitialContext;
import javax.persistence.EntityManager;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;public class Connection implements Serializable {private static final long serialVersionUID = 1L;/*** Get the user transaction by JNDI** @return the user transaction*/public UserTransaction getUserTransaction() {UserTransaction ut = null;try {Context c = new InitialContext();ut = (UserTransaction) c.lookup("java:comp/UserTransaction");} catch (Exception e) {e.printStackTrace();}return ut;}/*** Get the EntityManayger by JNDI** @return the entity manager*/public EntityManager getEntityManager() {EntityManager em = null;try {Context initCtx = new InitialContext();// The JSFPU must be written in the web.xmlem = (EntityManager) initCtx.lookup("java:comp/env/JSFPU");} catch (Exception e) {e.printStackTrace();}return em;}public void begin() throws NotSupportedException, SystemException {getUserTransaction().begin();}public void commit() throws SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException, SystemException {getUserTransaction().commit();}public int getStatus() throws SystemException {return getUserTransaction().getStatus();}public void rollback() throws IllegalStateException, SecurityException, SystemException {getUserTransaction().rollback();}public void setRollbackOnly() throws IllegalStateException, SystemException {getUserTransaction().setRollbackOnly();}public void setTransactionTimeout(int timeout) throws SystemException {getUserTransaction().setTransactionTimeout(timeout);}
}
我們可以使用JSF注入的UserTransaction,但是我們選擇使用JNDI查找。 有幾個在JSF上下文之外調用的Primefaces調用,如果嘗試訪問應注入的引用,則可能會出現NullPointerException。 有幾種方法可以解決此問題,但是我們將對EntityManager和UserTransaction使用JNDI查找。
我們的最后一堂課是PlayerDAO:
package com.dao;import java.io.Serializable;
import java.util.List;import javax.persistence.EntityManager;
import javax.persistence.Query;import com.connection.MyTransaction;
import com.model.Player;public class PlayerDAO implements Serializable {private static final long serialVersionUID = 1L;private MyTransaction myTransaction;public PlayerDAO(MyTransaction transaction) {this.myTransaction = transaction;}/*** Find players in the DB** @param startingAt the first "row" db that the query will search* @param maxPerPage the amount of records allowed per "trip" in the DB* @return a players java.util.List*/@SuppressWarnings("unchecked")public List<Player> findPlayers(int startingAt, int maxPerPage) {EntityManager em = myTransaction.getEntityManager();// regular query that will search for players in the dbQuery query = em.createQuery("select p from Player p");query.setFirstResult(startingAt);query.setMaxResults(maxPerPage);return query.getResultList();}/*** Creates 100 players in the DB*/public void create100Players() {EntityManager em = myTransaction.getEntityManager();Player player;for (int x = 0; x < 100; x++) {player = new Player();player.setName("Player: " + x);player.setAge(x);em.persist(player);}em.flush();}/*** Sum the number of players in the DB** @return an int with the total*/public int countPlayersTotal() {EntityManager em = myTransaction.getEntityManager();Query query = em.createQuery("select COUNT(p) from Player p");Number result = (Number) query.getSingleResult();return result.intValue();}
}
在PlayerDAO類中,只有3種方法可用于分頁。 注意,沒有方法可以列出數據庫中的所有玩家。
創建文件夾“ YOU_JBOSS / modules / org / hsqldb / main”。 在此文件夾中,創建一個名為“ module.xml”的文件。 將下面的代碼寫在“ module.xml”文件中:
<module xmlns="urn:jboss:module:1.0" name="org.hsqldb"><resources><resource-root path="hsqldb.jar" /></resources><dependencies><module name="javax.api" /><module name="javax.transaction.api" /></dependencies>
</module>
將“ hsqldb.jar”文件復制到剛創建的文件夾“ main”中。 您可以在下載的HSQLDB jar中找到此文件,其路徑為“ hsqldb-2.2.8.zip/hsqldb-2.2.8/hsqldb/lib”。
編輯文件“ YOU_JBOSS / standalone / configuration / standalone.xml”,然后在“數據源”節點中添加以下代碼:
<datasource jndi-name="java:/JSFDS" pool-name="JSFDS_POOL"enabled="true" jta="true" use-java-context="true" use-ccm="true"><connection-url>jdbc:hsqldb:mem:jsfinmemory</connection-url><driver>hsqldb</driver><pool><prefill>false</prefill><use-strict-min>false</use-strict-min><flush-strategy>FailingConnectionOnly</flush-strategy></pool><security><user-name>sa</user-name><password></password></security>
</datasource>
在驅動程序節點中添加:
<driver name="hsqldb" module="org.hsqldb"/>
參考: uaiHebert博客上我們JCG合作伙伴 Hebert Coelho的懶惰JSF數據表分頁(Primefaces) 。
翻譯自: https://www.javacodegeeks.com/2012/04/lazy-jsf-primefaces-datatable.html