懒惰的JSF Primefaces数据表分页–第1部分

今天,我们将使用带有视图范围的托管bean的惰性列表进行JSF数据表分页。 这些单词/表达式是什么意思?

如今,有几个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;
    }

    @Override
    public int hashCode() {
        return getId();
    }

    @Override
    public 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.xml
            em = (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 db
        Query 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
 JSF2.xdatatable分页控件与左侧菜单最简单应用   JSF2.x,功能强大,使用方便。全世界使用JSF的人越来越多。而且也有很多很好的控件给发出来了,如:richfaces、primefaces、myfaces等,就日前来讲primefaces功能很强大,控件很多,但有一点不好就是不支持IE6,特别是下拉列表,p:dialog等,其它的分页p:datatable实际使用起来总有不如意的地方。richfaces还支持可视化开发,可惜就是控件开发进度相比其它的慢了很多。下面帖我的控件的使用方法:   下载地址:http://download.csdn.net/detail/ptianfeng/4802713 一、分页具体使用方法如下(不多说,直接给你些颜色看看): 1. xhtml文件:    <html xmlns:ems="http://www.ems.com.cn" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets"> <h:dataTable id="tableId" value="#{userlogMBean.defaultDataModel}" var="var" rows="10"> <h:column> <f:facet name="header"> <h:outputText value="" /> </f:facet> <h:outputText value="#{var.sqlid}" /> </h:column> </h:dataTable> <ems:page id="pageId" for="tableId" maxPage="5" /> 2. 相应的Managedbean: [java] view plaincopy /** * EMS 11185 限时未达邮费奉还 * @author 螃蟹 */ @SuppressWarnings(value = "serial") @ManagedBean(name = "userlogMBean") @ViewScoped() public class UserlogMBean extends PageListBaseBean implements Serializable { public PagedListDataModel getDefaultDataModel() { if (defaultDataModel == null) { defaultDataModel = new PagedListDataModel(pageSize) { public DataPage fetchPage(int startRow, int pageSize) { ArrayList<UserlogVo> dataList = new ArrayList<UserlogVo>(); List<Userlog> list = dao.getObjectList(jpql, pageSize, startRow); if (list != null) { for (Userlog u : list) { UserlogVo vo = new UserlogVo(); vo.setSqlid(u.getSqlid()); vo.setCode(u.getCode()); vo.setDate(u.getDate()); vo.setStation(u.getStation()); vo.setUserid(u.getUserid()); vo.setText(u.getText()); dataList.add(vo); } } int size = dao.getCountOption(jpql); DataPage dataPage = new DataPage(size, startRow, dataList); return dataPage; } }; } return defaultDataModel; } } 提示:关于PageListBaseBean更多的信息,可以参阅我在百度的blog(百度改版后,让我很QF,所以转到CSDN来了): http://hi.baidu.com/kittopang/item/19af4e37c6ede2fae6bb7a11   至此,分页已经实现。下面是使用截图:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值