eXtremeTable之一(分页实现)

来源:互联网 发布:淘宝店小成本运营策略 编辑:程序博客网 时间:2024/04/29 14:17
 eXtremeTable这是之前韩老师讲过的一个分页组件,总结一下,供大家参考。看完这些基本上就可以架起eXtremeTable。有关eXtremeTable的其它应用,有时间再继续。
1.简介
eXtremeTable是目前流行的优秀分页组件之一,和 Displsytag,ValueList相比,即美观又使用。在介绍eXtremeTable之前先了解一下eXtremeComponents,它是一系列的开源的jsp自定义标签库,eXtremeTable是它中的一个功能强大而又容易配置、扩展、自定义的组件。它是以表格的形式来显示数据,具有分页组件应具有的大部分功能,比如:设定每页显示的记录数,排序等,除此之外它还具有过滤,导出,利用数据库的limit功能局部取数据,自定义列样式等等。eXtremeTable它不依赖任何框架和容器。
2.安装和测试
2.1 下载
eXtremeTable的最新版本为1.0.1,可以从它的官方网站http://www.extremecomponents.org下载最新版本,也可以从http://sourceforge.net/projects/extremecomp/下载.下载的压缩包为eXtremeComponents-1.0.1-with-dependencies.zip,解压后的主要目录如下所示:
(1)source:存放源文件
(2)lib:存放使用eXtremeTable一些功能所必需的jar包
(3)dist:使用eXtremeTable所必须的jar包和一些样式表,tld文件和js脚本文件。
(4)images:存放用表格显示数据时所用的图片。
(5)test:存放一个测试eXtremeTable的一个jsp文件。
2.2 安装
1.首先把必须的extremecomponents-1.0.1.jar放入WEB-INF/lib目录下,然后根据需要把解压包中lib目录下的jar文件拷贝到WEB-INF/lib目录下。尤其是minimum目录下的jar包也必须放入WEB-INF/lib目录下。
2.把css文件放到web应用的任意目录。
3.把images中的图片放到web应用的任意目录。
4.在/source/org/extremecomponents/table/core目录中找到extremetable.properties文件,把它复制到WEB-INF/classes里面(类加载器可以加载的地方)并根据需要进行相应修改,当然也可以不使用该文件。
2.3 测试该标签库
按照上面的步骤下载并安装后,我们就可以运行一个eXtremeTable例子。首先新建一个web工程并搭建好环境,然后写一个jsp页面来测试一下,代码如下:(当然我们也可以利用eXtremeTable压缩包中自带的例子test.jsp来测试,同样也可以看到效果)

<%@ page language="java" import="java.util.*" pageEncoding="GB2312"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ taglib uri="http://www.extremecomponents.org" prefix="ec" %>
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/styles/extremecomponents.css">
<%
    List countries = new ArrayList();
    for (int i = 1; i <= 10; i++)
    {
        Map cinfo = new java.util.HashMap();
        cinfo.put("cno", "coutry"+i);
        cinfo.put("cname", "国家"+i);
        cinfo.put("area", "所在州"+i);
        cinfo.put("born",new Date());
        countries.add(cinfo);
    }
    request.setAttribute("cinfos", countries);
%>
<ec:table
    items="cinfos"
    action="${pageContext.request.contextPath}/index.jsp"
    imagePath="${pageContext.request.contextPath}/images/table/*.gif"
    cellpadding="1"
    title="您好!这是eXtremeTable的一个测试例子">
<ec:row highlightRow="true">
<ec:column property="cno"/>
<ec:column property="cname"/>
<ec:column property="area"/>
<ec:column property="born" cell="date" format="yyyy-MM-dd"/>
</ec:row>
</ec:table>

把上面的工程部署到tomcat容器下,然后在浏览器地址栏里面输入:http://localhost:8080/pagination/index.jsp 浏览器显示的结果如下图所示:
图 2-1
3.eXtremeTable分页的原理
Extremecomponents默认从数据库中查找所有记录,如果结果集较大时,ec会使用Limit对象向Controller传递PageNo,PageSize,OrderBy等分页信息。而服务器端将向ec返回总记录数和当前页的内容。具体实现:
(1)从数据库获取数据并保存到Collection中
(2)将Collection保存在session或者request变量中
(3)在页面用taglib取出变量,遍历该Collection使之显示每条记录
4. eXtremeTable的应用
4.1 分页功能
分页是web应用程序最常见的功能,也是一个web开发者必须掌握的技能之一,在目前的IT开发节奏下不需要自己从头写分页功能,而是应该集成一个功能完善的分页组件。下面我们通过一个例子来看一下如何使用eXtremeTable的分页功能。
1. 首先构建一个web应用程序pagination,目录结构如下:
(1)itcast.cn.domain目录下存放的是employee.java,该程序是一个域对象与数据库中表employee相对应。
(2)itcast.cn.dao目录下存放的是EmployeeDao.java,该程序是一个接口负责定义操作数据库的CRUD方法。
(3)itcast.cn.dao.imp目录下存放的是接口EmployeeDao的实现类EmployeeDaoImp,该实现类负责从数据表employee中读取所有的记录。
(4)itcast.cn.dao.service目录下存放的是一个Servlet,负责把查询出来的结果集存放到request域中,并控制页面的跳转。
(5)images目录下存放显示页面所要用到的图片
(6)styles目录下存放的是css样式表
2. 把eXtremeComponents-1.0.1-with-dependencies.zip解压包中的dist目录和lib/minimum目录
   下的jar包拷贝到该应用程序的WEB-INF/lib目录下,把images目录下的图片拷贝到该应
   用程序下的images文件夹下面,把dist目录下的css样式表拷贝到该应用程序的styles目
   录下面。
3. 通过以上两步使用eXtremeComponents的环境基本上已经搭建好了,接下来就是具体的编
   码,为了减少篇幅,简单的代码就不给列出来了,相信大家都会写。
(1)模型组件employee代码如下:
例程4-1 employee.java

package itcast.cn.domain;
public class employee {
       private int emp_no;
       private String emp_name;
       private String emp_sex;
       private int dep_no;
       private String phone;
       public int getDep_no() {
              return dep_no;
       }
       public void setDep_no(int dep_no) {
              this.dep_no = dep_no;
       }
       public String getEmp_name() {
              return emp_name;
       }
       public void setEmp_name(String emp_name) {
              this.emp_name = emp_name;
       }
       public int getEmp_no() {
              return emp_no;
       }
       public void setEmp_no(int emp_no) {
              this.emp_no = emp_no;
       }
       public String getEmp_sex() {
              return emp_sex;
       }
       public void setEmp_sex(String emp_sex) {
              this.emp_sex = emp_sex;
       }
       public String getPhone() {
              return phone;
       }
       public void setPhone(String phone) {
              this.phone = phone;
       }
}

(2)context.xml,该文件负责创建数据源,存放到META-INF目录下,代码如下:
例程4-2 context.xml

<Context debug="5" reloadable="true" crossContext="true">
       <Resource name="jdbc/pagertest" auth="Container"
              type="javax.sql.DataSource" username="root" password="wang"
              driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql://localhost/pager?useUnicode=true&amp;characterEncoding=utf-8"
              maxActive="100" maxIdle="30" maxWait="10000" />
</Context>

(3)EmployeeDaoImp.java,代码如下:
例程4-3 EmployeeDaoImp.java

package itcast.cn.dao.imp;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import itcast.cn.dao.EmployeeDao;
import itcast.cn.domain.employee;
public class EmployeeDaoImp implements EmployeeDao {
              public List getemployees() {
              Context initCtx = null;
              List list = new ArrayList();
              try {
           //初始化一个InitialContext对象
                     initCtx = new InitialContext();
           //利用JNDI的名称得到数据源对象
                     DataSource ds = (DataSource) initCtx
                                   .lookup("java:comp/env/jdbc/pagertest");
          /* JdbcTemplate是Spring中的一个类,是对JDBC的一种封装,抽象出我们常用的方法。
          */
                     JdbcTemplate jdbctemplate = new JdbcTemplate(ds);
                     list = jdbctemplate.query("select * from employee",
                                   new RowMapper() {
             /*@ResultSet rs结果集,rnum当前行号*/
                                          public Object mapRow(ResultSet rs, int rnum)
                                                        throws SQLException {
                     //---------判断结果集的游标是否指向第一行之前
                                                 if (rnum < 0)
                                                        return null;
                                                 employee employee = new employee();
                                                 employee.setDep_no(rs.getInt(1));
                                                 employee.setEmp_name(rs.getString(2));
                                                 employee.setEmp_sex(rs.getString(3));
                                                 employee.setEmp_no(rs.getInt(4));
                                                 employee.setPhone(rs.getString(5));
                                                 return employee;
                                          }
                                   });
              } catch (Exception e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
              }
              return list;
       }
}

(4)EmployeeServlet.java 代码如下:
例程4-4 EmployeeServlet.java

package itcast.cn.service;
import itcast.cn.dao.imp.EmployeeDaoImp;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class EmployeeServlet extends HttpServlet {
       public void doGet(HttpServletRequest request, HttpServletResponse response)
                     throws ServletException, IOException {
              EmployeeDaoImp edao = new EmployeeDaoImp();
              List employees = edao.getemployees();
      // 把获得的list集合存放到request域中
              request.setAttribute("employees", employees);
      // 请求转发到test.jsp页面
              request.getRequestDispatcher("/test.jsp").forward(request,response);
       }
       public void doPost(HttpServletRequest request, HttpServletResponse response)
                     throws ServletException, IOException {
           doGet(request,response);
       }
}

(5)test.jsp,利用eXtremeComponents的标签库把查询出来的结果集以表格的形式显示出来
例程4-5 test.jsp

<%@ page language="java" import="java.util.*" pageEncoding="GB2312"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!--引入extremecomponents 的标签库-->
<%@taglib uri="http://www.extremecomponents.org" prefix="ec" %>
<!--引入extremecomponents 的样式表-->
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/styles/extremecomponents.css">
<ec:table
items="employees"
var="employee"
    action="${pageContext.request.contextPath}/servlet/EmployeeServlet"
    imagePath="${pageContext.request.contextPath}/images/table/*.gif"
    rowsDisplayed="5"
    width="700"
    title="员工信息">
<ec:row highlightRow="true">
<ec:column property="emp_no" alias="员工编号">
 ${employee.emp_no}
</ec:column>
<ec:column property="emp_name" alias="员工姓名"/>
<ec:column property="emp_sex" alias="性别"/>
<ec:column property="dep_no" alias="部门编号"/>
<ec:column property="phone" alias="联系电话"/>
</ec:row>
</ec:table>

说明:
(1)上面代码中的extremecomponents.css如果不引入仍然可以显示分页的效果,但是不会出现奇偶换行和高亮的效果。
 (2)<ec:table>中items属性用来设值存放在request域中的集合对象的名称,var属性值是集合对象的一个引用名称,通过该属性值可以获得集合对象中的属性值。action被用来告诉eXtremeTable当过滤或排序时如何回到当前的页面,本例中是通过EmployeeServlet来获得所有记录的集合。imagePath属性是用来显示图片的, 以上这几个属性都是必须的。rowsDisplayed是用来设置每一页显示的记录条数,如果不指定的话会使用默认的。widthtitle属性分别用来指定表格的宽度和标题,是可选的。
(3)<ec:row>表示一行,其中highlightRow表示是否显示高亮,如果属性值为true表示显示,否则不显示。<ec:column>表示列,property属性值对应前面定义的域对象employee中的属性,alials为列起一个别名。
4. 把整个pagination工程发部到tomcat的webapps下面,启动tomcat后在浏览器的地址栏中输入:http://localhost:8080/pagination/servlet/EmployeeServlet,将会看到如下所示的显示效果:
图 4-1
点击上面的next图标,在浏览器中将会看到如下结果:
图 4-2
同样点击Last图标将会看到最后几条记录。
5. 从上面运行的结果可知每一页显示的是5条记录,你也可以从右上角的下拉列表框中选择其它的记录条数,假如你选择的是10将会看到如下的结果:
                                                                  图 4-3         
如果你想要修改下拉列表框中的值,只需在src的根目录下添加一个属性文件extremecomponents.properties,并设置相应的属性便可,因为eXtremeComponents会自动读取该属性文件。代码如下:
table.rowsDisplayed=8
table.medianRowsDisplayed=10
table.maxRowsDisplayed=12
【注】如果在属性文件和jsp页面同时设置了rowsDisplayed属性,会以jsp页面的为主。
注意:一定要合理的使用alias ,title和property属性,如果使用不当就会影响页面的显示效果,一般会遇到下列情况:
(1)如果是通过<ec:column property=" emp_name "/>来显示从数据库中查询出一列的值则" emp_name "必须是表映射的实体中定义的属性,如果采用如<ec:column property="user" >${employee. emp_name }</ec:column>这种形式时,property属性的值可以任意指定。当然也可以用alias取别名代替但不可以仅仅用title来代替。如果使用<ec:column title=" emp_name ">${employee. emp_name }</ec:column>就会抛出java.lang.NullPointerException
(2)如果是使用<ec:column alias=" emp_name "/>则不能显示该列的数据,也就是说如果不使用EL表达式的形式来显示数据,那么就必须使用property属性且属性值必需是表映射的实体中定义的属性。
(3)如果三者同时使用优先级为title>alias>property,也就是说如果同时使用时以title设置的属性值为准,其次是alias,然后是property. 属性名相同时要制定alias。
 eXtremeTable的中文参考文档http://extremecomponents.org/wiki/index.php/Simplified_Chinese_Reference
 
 
 上面提到利用extremecomponents.properties来设置每一页显示的记录时,还需要在web.xml中配置一个全局的参数,代码如下:
        <context-param>
              <param-name>extremecomponentsPreferencesLocation</param-name>
              <param-value>/extremecomponents.properties</param-value>
       </context-param>
另:也可以直接在extremetable.properties中修改,而且该属性文件的名字可以是任意的(前面例子中采用的名字是extremecomponents.properties,不是必须的),但是都需要在web.xml中指定。
原创粉丝点击