primefaces4.0基本教程以及增删改查

最近试着用了用primefaces4.0,准备写一个基本的增删改查以及分页程序,但在写的过程中发现了很多问题,本想通过百度、谷歌解决,但无奈中文资料非常少,笔者在坑中不停的打滚,终于完成了一个有着基本功能的,还能看的过去的demo,想和大家一起分享一下,并希望能帮上和我一样陷入primefaces坑中的人。代码是仓促完成的,难免会有些缺点,还希望大家多多交流。http://www.mkyong.com/tutorials/jsf-2-0-tutorials/这个网站给了我非常大的帮助,在此表示严重感谢。

先来介绍一下primefaces吧,谈到primefaces,就要说到jsf了,jsf全称java server faces,简单来说就是一个Web 应用程序的新标准 Java 框架,而primeaces就是其中的一个实现,界面还是非常华丽的(笔者的意思是不大需要美工了),让笔者立刻想到了ExtJs...

接下来进入正题,先说说primefaces的基本环境配置

一、环境配置

    先到官方网站https://javaserverfaces.java.net/下载2.2.4版的jsf ,primefaces是基于它的,然后去http://www.primefaces.org/downloads.html下载primefaces-4.0.jar,还需要jstl.jar和standard.jar包,最后加上类似数据库连接等别的jar包,lib目录下就完成了。

再看web.xml,需要加入以下代码:

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
</servlet-mapping>

然后编写一个传统的helloworld程序来测试环境是否配置成功

show.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
    </h:head>
    <p:editor value=“hello world” />
</html>

打开浏览器,输入http://localhost:<端口号>/<项目名称>/faces/show.xhtml,如果看到如下结果,说明基本环境已经部署成功。


    这里要注意个问题,就是<h:head></h:head>一定要加上,否则primefaces不会渲染它,笔者曾被这个坑稍微折磨了那么一会。。

二、分页查询

    假设有如下实体类

PublicInfo.java

package test.entity;

import java.io.Serializable;
import java.util.Date;

public class Info implements Serializable
{
    private Integer id;
    private String title;
    private Date time;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Date getTime() {
        return time;
    }

    public void setTime(Date time) {
        this.time = time;
    }
}

在数据库中有一个与之对应的表,字段分别是id(number),title(varchar),time(date),这三个字段类型可以代表绝大多数情况。这里要注意,实体类要实现Serializable接口,否则可能会出现一些小问题。这里顺便说一下吧,因为jsf框架的设计导致了前台与后台的联系十分密切,所以,需要与前台交互的类一般都要实现Serializable接口。

primefaces内提供了一个类LazyDataModel,只要继承这个类,并实现它的三个方法,我们的后台分页就已经完成一半了,代码如下:

LazyInfoDataModel.java

package test.bean;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import test.entity.Info;

public class LazyInfoDataModel extends LazyDataModel<Info>
{
    private List<Info> list;

    public LazyInfoDataModel(){}

    @Override
    public List<Info> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,String> filters)
    {
        //这个方法不光可以实现分页,也可以实现过滤与排序
        /*我们暂时只实现简单的分页,
           first代表起始位置,pageSize代表查询数量,其他参数可以暂时不管,这两个参数就可以实现分页功能
           要查询出数据与数量
        */
        //setRowCount(数量); //这个方法一定要执行!

        //list = 查询结果
        return list;
    }

    @Override
    public Info getRowData(String rowKey)
    {
        for(Info info : list)
        {
            if(info.getId().toString().equals(rowKey))
            {
                return info;
            }
        }  

        return null;
    }  

    @Override
    public Object getRowKey(Info info)
    {
        return info.getId();
    }
}

后台还需要最后一部分,这一部分是与前台密切相关的,这个类主要负责与前台进行数据的交互,以及实现一些业务逻辑,代码如下:

InfoBean.java

package test.bean;

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.model.LazyDataModel;
import test.entity.Info;

@ManagedBean(name="infoBean")
@SessionScoped
public class InfoBean implements Serializable
{
    private LazyDataModel<Info> lazyModel = new LazyInfoDataModel();

    public LazyDataModel<Info> getLazyModel() {
        return lazyModel;
    }

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

这里还是要说明一下,@ManagedBean(name="infoBean")这个是jsf2的新特性,在jsf1中,需要写一个xml配置文件来配置,但jsf2取消了xml配置文件,改为使用注解。其中的name属性指定的值是在前台页面中这个类的别名,一会大家可以在前台页面的代码中看到。@SessionScoped表示作用域,其他的作用域还有@RequestScoped、@ViewScoped,看看名字大家就知道是怎么回事了,本教程的业务逻辑需要session作用域,所以就使用@SessionScoped了。

最后是前台部分了,直接上代码:

show.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
    </h:head>
    <h:form id="form1">
        <p:dataTable var="info" value="#{infoBean.lazyModel}" paginator="true" rows="10" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="5,10,15" id="infoTable" lazy="true">
            <p:column headerText="id">
                <h:outputText value="#{info.id}" />
            </p:column>

            <p:column headerText="title">
                <h:outputText value="#{info.title}" />
            </p:column>

            <p:column headerText="time">
                <h:outputText value="#{info.time}">
                    <f:convertDateTime timeZone="GMT+8" pattern="yyyy-MM-dd HH:mm:ss" locale="zh" />
                </h:outputText>
            </p:column>
        </p:dataTable>
    </h:form>
</html>

又要做一些说明了,大家注意看这个value="#{infoBean.lazyModel}",其中的infobean就是前面InfoBean的@ManagedBean(name="infoBean")中的属性,var="info",这个大家应该一看就知道了。还有时间处理<f:convertDateTime timeZone="GMT+8" pattern="yyyy-MM-dd HH:mm:ss" locale="zh" /> ,也要注意一下,然后就可以看看页面效果了。

以上就是分页查询的基本代码(好吧,测试数据是挺坑爹的...),大家可以看到,primefaces已经帮我们实现了分页,还可以指定每页显示的条数,大家快试试吧。

大家还可以参考官方的例子http://www.primefaces.org/showcase/ui/datatableLazy.jsf,在官方的例子中,还提供了过滤与排序的demo。

   

三、添加

    我们准备添加一个add按钮,弹出一个输入框,让用户输入要添加的信息,保存后刷新页面。

先上修改后的前台页面代码:

show.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
    </h:head>
    <h:form id="form1">
        <p:dataTable var="info" value="#{infoBean.lazyModel}" paginator="true" rows="10" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="5,10,15" id="infoTable" lazy="true">
            <p:column headerText="id">
                <h:outputText value="#{info.id}" />
            </p:column>

            <p:column headerText="title">
                <h:outputText value="#{info.title}" />
            </p:column>

            <p:column headerText="time">
                <h:outputText value="#{info.time}">
                    <f:convertDateTime timeZone="GMT+8" pattern="yyyy-MM-dd HH:mm:ss" locale="zh" />
                </h:outputText>
            </p:column>
        </p:dataTable>
    </h:form>   

    <p:commandButton value="add" onclick="PF(‘addDialog‘).show()" />

    <p:dialog header="add" widgetVar="addDialog" modal="true">
        <h:form id="form3">
            <h:panelGrid columns="2" cellpadding="5" id="addPanel">
                <p:outputLabel value="id" />
                <p:inputText value="#{infoBean.selected.id}" />

                <p:outputLabel value="title" />
                <p:inputText value="#{infoBean.selected.title}" />

                <p:outputLabel value="time" />
                <p:inputMask value="#{infoBean.selected.time}" mask="9999-99-99 99:99:99">
                    <f:convertDateTime timeZone="GMT+8" pattern="yyyy-MM-dd HH:mm:ss" locale="zh" />
                </p:inputMask>

                <p:commandButton value="confirm" oncomplete="PF(‘addDialog‘).hide()" actionListener="#{infoBean.add}" update=":form1:infoTable,form3"  />
            </h:panelGrid>
        </h:form>
    </p:dialog>
</html>

又到了说明的时间了,与之前的show.xhtml相比,我们增加了一个<p:commandButton />和一个<p:dialog />,注意一下这里<p:inputMask value="#{infoBean.selected.time}" mask="9999-99-99 99:99:99">,我们使用了一个<p:inputMask />标签,这个标签可以限制用户的输入格式,这样转成date就更加方便了。还有一点需要注意,我们用了一个id为form3的<h:form />标签将需要提交的信息包在里面,一定要加上这个form,否则会有一些不大好解释的问题,笔者之前又被这个问题小折磨了会。。还要注意actionListener="#{infoBean.add}"和update=":form1:infoTable,form3",通过actionListener可以看到jsf中前台与后台是如何进行交互的,update表示执行完这个表单提交需要更新的地方,我们要更新查询页面,也要更新自己的form3,否则当用户再想增加新内容时,看到已经填好了信息,他会不会迷惑呢。。。

再是后台代码:

InfoBean.java

package test.bean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
import org.primefaces.model.LazyDataModel;import test.entity.Info;

@ManagedBean(name="infoBean")
@SessionScoped
public class InfoBean implements Serializable
{
    private LazyDataModel<Info> lazyModel = new LazyInfoDataModel();
    private Info selected = new Info();

    public void add(ActionEvent e)
    {
//在这里写上向数据库保存的内容的代码,selected就是前台传来的待保存信息

        selected = new Info(); //由于是session作用域,会存在脏数据的问题,我们清除它
    }

    public LazyDataModel<Info> getLazyModel() {
        return lazyModel;
    }

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

    public Info getSelected() {
        return selected;
    }

    public void setSelected(Info selected) {
        this.selected = selected;
    }
}

我们增加了一个selected和一个add方法,具体的对应关系和前台的参照一下

然后是效果图:

我们添加一个id为2的数据,提交

可以看到,id为2的那条数据已经添加进去了。

四、更新&删除

    前台代码:

show.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"
      xmlns:pt="http://xmlns.jcp.org/jsf/passthrough">
    <h:head>
    </h:head>
    <h:form id="form1">
        <p:dataTable var="info" value="#{infoBean.lazyModel}" paginator="true" rows="10" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="5,10,15" id="infoTable" lazy="true">
            <p:column headerText="id">
                <h:outputText value="#{info.id}" />
            </p:column>

            <p:column headerText="title">
                <h:outputText value="#{info.title}" />
            </p:column>

            <p:column headerText="time">
                <h:outputText value="#{info.time}">
                    <f:convertDateTime timeZone="GMT+8" pattern="yyyy-MM-dd HH:mm:ss" locale="zh" />
                </h:outputText>
            </p:column>

            <p:column headerText="">
                <p:commandButton value="delete">
                    <p:ajax event="click" listener="#{infoBean.select(info)}" oncomplete="PF(‘delDialog‘).show()" />
                </p:commandButton>
                <p:commandButton value="update">
                    <p:ajax event="click" listener="#{infoBean.select(info)}" oncomplete="PF(‘updateDialog‘).show()" update=":form4" />
                </p:commandButton>
            </p:column>
        </p:dataTable>
    </h:form>    

    <p:dialog header="Are you sure?" widgetVar="delDialog" modal="true">
        <h:form id="form2">
            <h:panelGrid columns="2" cellpadding="5" id="addPanel">
                <f:facet name="facet1">
                    <p:outputLabel value="Are you sure?" />
                </f:facet>

                <p:commandButton value="yes" actionListener="#{infoBean.delete}" update=":form1:infoTable" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" oncomplete="PF(‘delDialog‘).hide()" />
                <p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close" oncomplete="PF(‘delDialog‘).hide()" />
            </h:panelGrid>
        </h:form>
    </p:dialog>

    <p:commandButton value="add" onclick="PF(‘addDialog‘).show()" />

    <p:dialog header="add" widgetVar="addDialog" modal="true">
        <h:form id="form3">
            <h:panelGrid columns="2" cellpadding="5" id="addPanel">
                <p:outputLabel value="id" />
                <p:inputText value="#{infoBean.selected.id}" />

                <p:outputLabel value="title" />
                <p:inputText value="#{infoBean.selected.title}" />

                <p:outputLabel value="time" />
                <p:inputMask value="#{infoBean.selected.time}" mask="9999-99-99 99:99:99">
                    <f:convertDateTime timeZone="GMT+8" pattern="yyyy-MM-dd HH:mm:ss" locale="zh" />
                </p:inputMask>

                <p:commandButton value="confirm" oncomplete="PF(‘addDialog‘).hide()" actionListener="#{infoBean.add}" update=":form1:infoTable,form3"  />
            </h:panelGrid>
        </h:form>
    </p:dialog>

    <p:dialog header="update" widgetVar="updateDialog" modal="true">
        <h:form id="form4">
            <h:panelGrid columns="2" cellpadding="5" id="addPanel">
                <p:outputLabel value="id" />
                <p:inputText value="#{infoBean.selected.id}" readonly="true" />

                <p:outputLabel value="title" />
                <p:inputText value="#{infoBean.selected.title}" />

                <p:outputLabel value="time" />
                <p:inputMask value="#{infoBean.selected.time}" mask="9999-99-99 99:99:99">
                    <f:convertDateTime timeZone="GMT+8" pattern="yyyy-MM-dd HH:mm:ss" locale="zh" />
                </p:inputMask>

                <p:commandButton value="confirm" oncomplete="PF(‘updateDialog‘).hide()" actionListener="#{infoBean.update}" update=":form1:infoTable"  />
            </h:panelGrid>
        </h:form>
    </p:dialog>
</html>

注意一下这里<p:ajax event="click" listener="#{infoBean.select(info)}" oncomplete="PF(‘updateDialog‘).show()" update=":form4" />,这里是笔者在做这个项目的过程中遇到的最头疼的问题,这里涉及到一个传值的问题,原来笔者是这么写的<p:commandButton actionListener="#{infoBean.select(info)}" oncomplete="PF(‘updateDialog‘).show()" />,而且primefaces官方demo也是这么写,但笔者在测试时发现,这样写会先调用oncomplete,显示dialog,然后再调用actionListener,在dialog显示的时候后台还没有接受到值,所以会报错,估计是笔者运气好吧,想到了一个这样的方法,可以解决这个问题。

后台代码

InfoBean.java

package test.bean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
import org.primefaces.model.LazyDataModel;import test.entity.Info;

@ManagedBean(name="infoBean")
@SessionScoped
public class InfoBean implements Serializable
{
    private LazyDataModel<Info> lazyModel = new LazyInfoDataModel();
    private Info selected = new Info();

    public void select(Info selected)
    {
        this.selected = selected;
    }

    public void add(ActionEvent e)
    {
        //jdbc

        selected = new Info();
    }

    public void update(ActionEvent e)
    {
        //jdbc

        selected = new Info();
    }

    public void delete(ActionEvent e)
    {
        //jdbc

        selected = new Info();
    }

    public LazyDataModel<Info> getLazyModel() {
        return lazyModel;
    }

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

    public Info getSelected() {
        return selected;
    }

    public void setSelected(Info selected) {
        this.selected = selected;
    }
}
时间: 2024-10-20 13:02:32

primefaces4.0基本教程以及增删改查的相关文章

Yii2.0高级框架数据库增删改查的一些操作(转)

yii2.0框架是PHP开发的一个比较高效率的框架,集合了作者的大量心血,下面通过用户为例给大家详解yii2.0高级框架数据库增删改查的一些操作 ----------------------------------------------------------------------------------------------------- User::find()->all();    //返回所有用户数据:User::findOne($id);   //返回 主键 id=1  的一条数

Yii2.0高级框架数据库增删改查的一些操作

yii2.0框架是PHP开发的一个比较高效率的框架,集合了作者的大量心血,下面通过用户为例给大家详解yii2.0高级框架数据库增删改查的一些操作 ----------------------------------------------------------------------------------------------------- User::find()->all();    //返回所有用户数据:User::findOne($id);   //返回 主键 id=1  的一条数

NetCore2.0 RozarPage自动生成增删改查

原文链接:https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/web-api-help-pages-using-swagger 上面的只是原文的上面的链接,右边的 没有链接,不能点击,不知道为什么.不过大家可以点击下面的下载PDF,下载后打开看就可以了 准备工作 VS2017需要15.3以后的版本,且安装完NetCore2.0 SDK Net Core 2.0 SDK下载链接:https://www.microsoft.com/net/c

mysql存储过程+事件统计mysql增删改查qps

/*统计mysql增删改查 qps 的sql脚本*/; DROP TABLE IF EXISTS  qpsInfo ; CREATE TABLE qpsInfo( id INT PRIMARY KEY AUTO_INCREMENT, `type` INT COMMENT "1 insert,2 delete,3 update,4 select", `count` INT COMMENT "更新的总数", `qps` INT COMMENT "10秒钟更新的

微软Connect教程系列--自动生成增删改查页面工具介绍(二)

本章课程描述了vs2015的三个特点,其中主要将描述在vs2015下面,使用命令自动生成增删改查界面,具体如下: 1.web.config文件不在存在,用config.json替代,以适应支撑vs的插件化. 即config.json可以在项目中不存在,你可以用xml文件或其他方式创建数据库连接. 2.获取nuget包更便捷 打开project.json,在dependencies节点输入“Newtonsoft.json”,并选择好相应版本,保存后,vs的引用就会自动从nuget上下载newton

MongoDB 3.0.6 安装 增删改查

下载 安装包MSI http://yunpan.cn/cmhHdTPkXZRM2  访问密码 9b6c 上边提供的是 MongoDB 3.0.6 64Bit 的安装包 安装 如果不想直接安装在C盘..就要选择自定义安装喽.. 就是选择全部安装和自定义的那一步..全部安装是默认安装C盘的.. 我这里是安装到 D:\Program Files\MongoDB\MongoDB 的.. 需要在 D:\Program Files\MongoDB 下新建 Log 文件夹..并在Log下建立 Log.txt

MVC ---- EF4.0和EF5.0增删改查的写法区别及执行Sql的方法

EF4.0和EF5.0增删改查的写法区别 public T AddEntity(T entity) { //EF4.0的写法 添加实体 //db.CreateObjectSet<T>().AddObject(entity); //EF5.0的写法 db.Entry<T>(entity).State = EntityState.Added; //下面的写法统一 db.SaveChanges(); return entity; } public bool UpdateEntity(T

Mysql 常用增删改查命令集合教程

创建:create      插入:insert 更新:update  查询:select 删除:delete 修改:alter     销毁:drop 创建一个数据库: create database 数据库名 [其他选项]; create database `samp_db`;创建数据库表: create table 表名称(列声明); create table `students` ( `id` int unsigned not null auto_increment primary ke

YII2.0 数据库增删改查

/*==================== dkhBaseModel 数据库增删改查方法 start ================================*/ //新增一条数据 public function baseInsertData($data){ if(!is_array($data)) {return $this->setError(['errmsg'=>'data Error']);}; $db = \Yii::$app->db; $ok = $db->c