`
huxiaojun_198213
  • 浏览: 102787 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Lazy JSF Primefaces Datatable Pagination – Part 1

    博客分类:
  • JSF
阅读更多
Lazy JSF Primefaces Datatable Pagination – Part 1

Today we will do JSF datatable pagination with a Lazy List with a view scoped managed bean. What all those words/expressions mean?

There are several JSF frameworks today that provide datatables with a ready pagination, columns sorter and others functionalities. Today we will use the Primefaces datatable.

Usually the datatables will put the displayed List, with the entities, inside the user http session. Increasing the objects inside the user session will have a direct impact on the server performance; each user that displays a datatable, that keeps a list in the session, will be allocating more and more memory in the server.

To look like real life, our post will use JPA and HSQLDB as database, and we will use JPQL to query the data.

In the end of this post you will find the link to download the source code.

We will use:
■JSF 2.0 – JBoss 7 Implementation
■JBoss 7.1 – the code of this post should be applied to all servers
■Eclipse Indigo
■JPA 2.0 – JBoss 7 Implementation
■HSQLDB (2.2.8) – The HSQL it is a memory database, it will be easier to run it.
■Primefaces 3.2

This post is not about good development practices nor about adding classes layers of project modeling. I just intend to show how to do a pagination without a session managed bean.

We will have only one entity that will be persisted, the Player class. Bellow the class code:

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



We will need to create a persistence.xml file inside the “src/META-INF” folder:

<?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>



To abstract the database transaction we will use a class named 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();
    }
}



You can see in the code above that the class is just an abstraction to the database connection; it will help us with the database queries.

You could use any type of connection or you could use even a EJB to be avoiding this manually connection management.

Check the Connection class code:
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);
    }
}



We could use an injected UserTransaction by the JSF but we chose to use JNDI lookup.

There are several Primefaces calls that are invoked outside the JSF context, you may get some NullPointerException if you try to access the references that should be injected.

There are several ways to work with this issue, but we will use the JNDI Lookup to the EntityManager and to the UserTransaction.

Our last class will be the 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();
    }
}


In the PlayerDAO class we have only 3 methods to work with our pagination. Notice that there is no method to list all the players in our database.

Create the folder “YOU_JBOSS/modules/org/hsqldb/main“. Inside this folder create a file named “module.xml“. Write the code bellow inside the “module.xml” file:

<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>



Copy the “hsqldb.jar” file to the folder “main” that you just created. This file you will find inside the HSQLDB jar you download in the path “hsqldb-2.2.8.zip/hsqldb-2.2.8/hsqldb/lib“.

Edit the file “YOU_JBOSS/standalone/configuration/standalone.xml” and add the code bellow in the “datasources” node:

<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>



In the drivers node add:

<driver name="hsqldb" module="org.hsqldb"/>


from:http://www.javacodegeeks.com/2012/04/lazy-jsf-primefaces-datatable.html
分享到:
评论

相关推荐

    JSF-2-DataTable

    **JSF 2.0 DataTable 全面解析** JavaServer Faces (JSF) 是一个用于构建用户界面的Java EE框架,特别适用于开发Web应用程序。在JSF 2.0版本中,DataTable组件是一个核心功能,它允许开发者以表格形式展示数据,...

    jsf 分页实例jsf 分页实例

    在JSF中,可以使用开源库如PrimeFaces、RichFaces或ICEfaces等提供的分页组件。这里以PrimeFaces为例,因为它拥有广泛的应用和丰富的组件库。PrimeFaces的`p:datascroller`组件是用于分页的理想选择。 ### 2. 添加...

    PrimeFacesJSF框架JavaServerFaces组件套件

    - **DataTable Extensions**:如LazyLoading和ColumnGroup,进一步增强DataTable的功能。 **集成PrimeFaces到JSF项目** 1. 添加PrimeFaces的依赖库到项目的类路径,通常通过Maven或Gradle进行管理。 2. 在JSF配置...

    基于primefaces对table的增删改查的源码

    1. **分页和懒加载**: 使用`&lt;p:paginator&gt;`组件和`lazy="true"`属性实现大数据集的高效展示。 2. **验证(Validation)**: 添加验证规则,确保用户输入的数据符合业务需求。 3. **国际化(Internationalization)*...

    jsf自带分页

    在JSF中,分页通常与数据表组件结合使用,例如PrimeFaces中的`p:dataTable`。这个组件支持内建的分页功能,可以通过设置属性`rows`定义每页显示的行数,`paginator`属性开启分页,`paginatorTemplate`自定义分页按钮...

    datatable+bootstrap

    1. **DataTable插件基础**:DataTable提供了一种灵活的方式来展示和操作表格数据,包括排序、搜索、分页等功能。它可以通过JavaScript对象进行初始化,设置各种配置项,如列定义、数据源等。 2. **Bootstrap集成**...

    lazyload-2.x.zip

    1. **基本配置**:jQuery LazyLoad提供了丰富的配置选项,以满足不同场景的需求。例如: ```javascript $(".lazy").lazyload({ threshold : 200, // 图片距离视口边缘的最小距离触发加载 event : "scroll", // ...

    C#使用Lazy延迟加载

    1. **延迟加载(Lazy Loading)**:延迟加载是一种设计模式,其核心思想是推迟对某些对象或数据的初始化,直到它们被实际需要时才进行。这在处理大型数据集或需要耗时初始化的对象时特别有用,因为它可以减少启动...

    Lazy

    Lazy

    LazyUI-dependency

    标题提到的"LazyUI-dependency"表明这是一个关于懒加载用户界面(LazyUI)的依赖集合,可能是为了帮助开发者更方便地集成到自己的项目中,尤其是对于那些不熟悉或者不喜欢使用Maven进行依赖管理的开发者。...

    jQuery_lazyload

    jQuery_lazyload是一个非常实用的JavaScript库,用于优化网页性能,特别是在处理大量图片或者内容时。这个插件的主要目的是延迟加载,即在用户滚动到页面的特定部分时才加载那些可视区域以外的内容,从而减少初次...

    lazyload.js演示页面

    1. **设置图片宽高**:由于`lazyload.js`默认使用一像素的占位符,如果未设置图片的实际宽高,浏览器可能会认为所有图片都是1像素大小。因此,为了防止图片在滚动时提前加载,每个图片元素应预设正确的宽度和高度。...

    datatable例子 超大表格

    3. **延迟加载**(Lazy Loading):只有在用户滚动到可视区域时才加载额外的数据行,这可以显著减少初始加载时间。 4. **列宽调整**:Datatable 允许用户动态调整列宽,以适应不同大小的数据和屏幕。 5. **搜索和...

    JQuery Lazyload加载图片实例

    **jQuery Lazyload 图片加载技术详解** 在网页设计中,图片是重要的元素之一,但大量图片的预加载可能会拖慢页面的加载速度,影响用户体验。为了解决这一问题,jQuery 提供了一个插件——jQuery Lazyload,它允许...

    懒加载lazyload

    懒加载(Lazy Load)是一种网页优化技术,主要应用于图片、视频等大容量媒体资源的加载。它的核心思想是延迟加载,即在用户滚动页面时,只加载可视区域内的元素,而不是一次性加载整个页面的所有资源。这极大地提高...

    jquery.lazyload.js

    《jQuery.Lazyload.js:优化网页加载速度与用户体验的艺术》 在现代网页设计中,页面加载速度和用户体验是至关重要的因素。jQuery.Lazyload.js是一个高效实用的JavaScript插件,它能够显著提升网页加载速度,同时...

    jquery lazyload延时加载

    1. **引入 jQuery 和 LazyLoad**:首先确保页面中已经引入了 jQuery 库,然后引入 LazyLoad 的 JavaScript 文件,如 `jquery.lazyload.js`。 2. **设置 HTML 结构**:给需要延时加载的图片添加特定的类名(如 `lazy...

    magento lazyload插件

    Magento LazyLoad 插件是针对Magento电子商务平台设计的一款性能优化工具。它的主要功能是实现图片的延迟加载(Lazy Load),以此提升网站的加载速度和用户体验。在网页浏览时,传统方式下所有图片会一次性全部加载...

    图片延迟加载 lazyload

    图片延迟加载(Lazy Load)是一种优化网页性能的技术,主要用于处理大量图片或多媒体资源的加载。在网页设计中,当用户滚动页面时,只有进入视口的图片才会开始加载,而那些还未显示出来的图片则会暂时保持占位符...

Global site tag (gtag.js) - Google Analytics