一、Pager-taglib数据库分页前提
  
Pager-taglib分页标签也可以实现数据库分页,与页面分页不同的是需要给后台传两个参数,一个是pageNo(当前页数)或pageOffset(偏移量),另一个参数是pageSize(分页尺寸)。数据库分页的实质是根据页面传递过来的这两个参数从数据库中提取部分记录(而不是所有记录),然后由页面呈现这些数据。因每次只装载一部分数据,因而占据少量内存,适合大量数据查询。

 二、SSH数据库分页示例(通用设计)

  1、准备工作
   首先下载pager-taglib-2.0.war
,地址http://jsptags.com/tags/navigation/pager/download.jsp,然后将lib下面的包lib下的jar包放到自己项目的lib下面。

生成测试表:t_person,其中实体类Person类有id,name,phone属性,具体在hibernate配置文件中的配置略..。

 
2、分页实体类设计

   
创建PagerModel类用于存放从数据库查询的所有person,和总记录数。
   public class PagerModel
{
    private int
total;//总记录数
    private List
datas;//所有用户集合
   
...get和set方法
   }

  
3.编写通用数据访问组件

    import org.hibernate.Query;
import
org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class BaseHibernateDao  extends
HibernateDaoSupport
{
   
//根据多个查询条件params获取指定页的记录集。offset:页面记录的开始位置,即偏移量
   
//pageSize:页面尺寸
    public
PagerModel searchPagerModel(String hql,Object[] params,int
offset,int pageSize)
    {
   
   
//获取查询记录总数hql语句
   
    String
countHql = getCountQuery(hql);
   
   
 Query query
=getSession().createQuery(countHql);
   
   
 if(params!=null
&&
params.length>0)
   
   
 {
   
   
   
 for(int
i=0;i<params.length;i++)
   
   
   
 {
   
   
   
   
 query.setParameter(i, params[i]);
   
   
   
 }
   
   
 }
   
   
 //获取总记录的条数
   
   
 int total = ((Long)
query.uniqueResult()).intValue();
   
   
 //获取当前页面的结果集
   
   
 query =
super.getSession().createQuery(hql);
   
   
 if(params!=null
&&
params.length>0)
   
   
 {
   
   
   
 for(int
i=0;i<params.length;i++)
   
   
   
 {
   
   
   
   
 query.setParameter(i, params[i]);
   
   
   
 }
   
   
 }
   
   
 query.setFirstResult(offset);
   
   
 query.setMaxResults(pageSize);
   
   
 PagerModel pagerModel = new PagerModel();
   
   
 //设置当前页面记录和总记录数
   
   
 pagerModel.setDatas(query.list());
   
   
 pagerModel.setTotal(total);
   
   
 return pagerModel;
    }
   
//重载方法:根据单个查询条件param获取指定页的记录集。
    public
PagerModel searPagerModel(String hql ,Object param)
    {
   
    return
this.searchPagerModel(hql, new Object[]{param},
SystemContext.getOffset(), SystemContext.getPagesize());
    }
    public
PagerModel searchPagerModel(String hql)
    {
   
    return
this.searchPagerModel(hql, null, SystemContext.getOffset(),
SystemContext.getPagesize());
    }
    public
PagerModel searchPagerModel(String hql ,Object[] params)
    {
   
    return
this.searchPagerModel(hql, params, SystemContext.getOffset(),
SystemContext.getPagesize());
    }
   
   
   
//根据hql语句,获得查找总记录数的hql语句
    private
String getCountQuery(String hql)
    {
   
    int index
=hql.indexOf("from");
   
    if(index
!=-1)
   
    {
   
   
    return
"select count(*)"+hql.substring(index);
   
    }
   
    throw new
RuntimeException("无效的HQL查询语句");
    }
}
 
有了BaseHibernateDao组件,我们的PersonServiceImpl改写为:
  public  class PersonServiceImpl
extends

BaseHibernateDao implements PersonService
   {
    
public PagerModel searchPerson(int offset,int pageSize){
     
String hql ="from Person as person order by person.id desc";
     
return super.searchPagerModel(hql,null,offset,pageSize);
    
}

}
  4.编写过滤器及其相关组件(可以将它们放在同一个包下)
   4.1、编写SystemContext组件

将系统启动时显示起始记录数和每页显示行数设置在ThreadLocal中。
    public class SystemContext
{

//用于query.setFirstResult(offset)
   
private static ThreadLocal < Integer
> offset = new ThreadLocal < Integer
> ();

//pagesize每页显示的行数用于

//query.setMaxResults(pagesize); 
 
   
private static ThreadLocal < Integer
> pagesize = new ThreadLocal <
Integer > ();

   
-----ThreadLocal线程局部变量,
就是为每一个使用该变量的线程都提供一个变量值的副本,每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突,
也就是每一个用户都可以改变自己的每页显示的行数而不会影响到其他人

public
static void setOffset(int offsetvalue)
    {
   
   
offset.set(offsetvalue);
    }
    public
static int getOffset()
   
 {
   
    Integer ov =
offset.get();
   
    if (ov ==
null) {
   
   
    return
0;
   
    }
   
    return
ov;
    }

public
static void setPagesize(int pagesizevalue)
    {
   
   
pagesize.set(pagesizevalue);
    }

public
static int getPagesize()
    {
   
    Integer ps =
pagesize.get();
   
    if (ps ==
null) {
   
   
    return
Integer.MAX_VALUE; //将pagesize设置为无穷大,也就是显示在一页上
   
    }
   
    return
ps;
    }
    public
static void removeOffset()
   
 { //清除为每个用户分配的副本
   
   
offset.remove();
    }
    public
static void removePagesize() {
   
   
pagesize.remove();
    }
}

4.2Env组件(加载配置文件)
public class  Env extends
Properties
{
    private
static Env env;
    public
static Env getInstance()
    {
   
   
makeInstance();
   
    return
env;
    }
   
//以单例模式创建对象
    private
static synchronized void makeInstance()
    {
   
    if (env
==null) {
   
   
    env = new
Env();
   
    }
    }

private
Env()
    {
   
   
//该属性文件含有pageModel_pageSize属性(分页尺寸)
   
    InputStream
inStream=getClass().getResourceAsStream("/env.Properties");
   
    try
   
    {
   
   
   
super.load(inStream);
   
    }
   
    catch
(IOException)
   
    {
   
   
   
e.printStackTrace();
   
    }
    }

}
  4.3、PagerFilter组件
  用于设置加载用户自定义的pagesize和offset
  public class PagerFilter
implements Filter
 {
  public void doFilter(ServletRequest request,
ServletResponse response,
  FilterChain chain) throws IOException,
ServletException {

HttpServletRequest httpRequest = (HttpServletRequest)
request;
   
//设置分页参数:偏移量和页面尺寸
   
SystemContext.setOffset(getOffset(httpRequest));
   
SystemContext.setPagesize(getPagesize());

try {
     
chain.doFilter(request, response);
    } finally
{
     
SystemContext.removeOffset();
     
SystemContext.removePagesize();
    }
  }
  private int getOffset(HttpServletRequest
httpRequest) {
    int offset =
0;
    try {
     
offset =
Integer.parseInt(httpRequest.getParameter("pager.offset"));
//得到标签自己计算出的pager.offset
    } catch
(Exception ignore) {}
    return
offset;
  }
  //获取每页显示的行数
  private int getPagesize()
  {
     
int pageSize = 0;
     
try
{      
pageSize=Integer.parseInt(Env.getInstance().getProperty("pageModel_pageSize"))

} catch (NumberFormatException e) {
         
pageSize = Integer.MAX_VALUE;
     
}
     
return pageSize;

}

}
在web.xml中配置:
   
<filter>
    
<filter-name>pagerfilter</filter-name>

<filter-class>com.test.filter.PagerFilter</filter-class>

</filter>
  
<filter-mapping>
   
<filter-name>pagerfilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

 
5、控制器PersonAction核心代码(部分)

    public
String getPersons()
   {
     
....省略得到session定义
     
PagerModel pm
=PersonService.searchPerson(pageOffset,pageSize);
     
session.setAttribute("pm",pm);
     
return "success";//sucess配置转向的是pager_index.jsp页面
   }
 
说明:我们已经在该actin中定了了pageOffset的get/set方法;pageSize是我们写死的(如pageSize=4),并且已经提供了get方法(供EL表达式调用)

 
6、配置分页风格组件:pager_conn.jsp(重点)

  <%@ taglib prefix="pg"
uri="http://jsptags.com/tags/navigation/pager"
%>
<%@ taglib
prefix="c"   
uri="http://java.sun.com/jsp/jstl/core"
%>   
 

   
 <pg:pager
url="personAction!getPerson" 
items="${pm.total}"
maxPageItems = "${pageSize}"
maxIndexPages="3" export="pageOffset,currentPageNumber=pageNumber"
isOffset="false" 
index="half-full" 
>
 
  <%--
是否向后台传参:personAction!getPerson?method=${parm}
   
<c:if test="${not empty param
}">
   
   
<pg:param name="method" value="${param
}"/>
   
</c:if>

--%>

<pg:first>

<a
href="${pageUrl}">首页</a>

</pg:first>

<pg:prev>

<a href="${pageUrl
}">上一页</a>

</pg:prev>

<pg:pages>

<c:choose>

<c:when test="${currentPageNumber eq
pageNumber}">

<font color="red">${pageNumber
}</font>

</c:when>

<c:otherwise>

<a href="${pageUrl }">${pageNumber
}</a>

</c:otherwise>

</c:choose>

</pg:pages>

<pg:next>

<a href="${pageUrl
}">下一页</a>

</pg:next>

<pg:last>

<a href="${pageUrl
}">尾页</a>

</pg:last>

</pg:pager> 
 
  
注意:数据库分页和页面分页不用的是:页面分页分页内容和分页风格是耦合在一起的;数据库分页分页内容和分页风格是对立的(即pg:paper根元素中不会含有分页内容)

 7、分页内容文件pager_index.jsp

<%@ taglib
prefix="c"   
uri="http://java.sun.com/jsp/jstl/core"
%> 
  

       
<table width="778" border="0" cellPadding="0"
cellSpacing="1"
bgcolor="#6386d6">

<tr
bgcolor="#EFF3F7">

<TD
align="center">ID</TD>

<TD
align="center">姓名</TD>

<TD
align="center">电话</TD>

</tr>

<c:if test="${!empty
pm.datas}">

<c:forEach items="${pm.datas}"
var="person">

<tr
bgcolor="#EFF3F7">

<td align="center">${person.id
}</td>

<td align="center">${person.name
}</td>

<td
align="center">${person.phone}</td>

</tr>

</c:forEach>

</c:if>

<c:if test="${empty
pm.datas}">

<tr>

<td colspan="5" align="center"
bgcolor="#EFF3F7">

没有找到相应的记录  
           
</td>

</tr>

</c:if>

</table>

<jsp:include
page="/WEB-INF/jsp/
pager_conn.jsp"
flush="true"></jsp:include>

说明:
 
上面使用的动态包含,但前提是:要包含的
风格文件pager_conn.jsp能够独立编译(即一定要导入6中的两个jsp页面指令);如何使用静态包含也可以,前提是:两页面合并后一定要能正确编译(即合并后一定要有6中的两个jsp页面指令,合并前这两个指令分散在哪个页面无所谓


 三、总结
   
pager便签库有两种自行计算分页参数(pageOffset)的方式:一种是根据pg:pager的items属性(设置总记录数)
和maxPageItems属性(设置一页的记录数),适用于数据库分页;另一种是根据pg:pager的maxPageItems属性(设置页尺寸)和pg:item标签,这种适合页面分页。

风格

分页技术框架(Pager-taglib)学习二(SSH数据库分页)的更多相关文章

  1. 分页技术框架(Pager-taglib)学习一(页面分页)

    一.Pager-taglib简介     1.Pager-taglib,支持多种风格的分页显示.实际上她是一个Jsp标签库,为在JSP上显示分页信息而设计的一套标签,通过这些标签的不同的组合,会形成多 ...

  2. 分页技术框架(Pager-taglib)学习三(pager-taglib中传递参数时中文乱码问题)

    一.问题描述 问题: 使用<pg:param name="key" />标签传递中文参数时,会有乱码. 原因: 因为它默认是用gb2312来对添加的参数进行编码,如果你 ...

  3. go微服务框架go-micro深度学习(二) 入门例子

    上一篇帖子简单介绍了go-micro的整体框架结构,这一篇主要写go-micro使用方式的例子,中间会穿插一些go-micro的源码,和调用流程图,帮大家更好的理解go-micro的底层.更详细更具体 ...

  4. go微服务框架go-micro深度学习-目录

    go微服务框架go-micro深度学习(一) 整体架构介绍 go微服务框架go-micro深度学习(二) 入门例子 go微服务框架go-micro深度学习(三) Registry服务的注册和发现 go ...

  5. MySQL、SqlServer、Oracle三大主流数据库分页查询

    在这里主要讲解一下MySQL.SQLServer2000(及SQLServer2005)和ORCALE三种数据库实现分页查询的方法.可能会有人说这些网上都有,但我的主要目的是把这些知识通过我实际的应用 ...

  6. Handsontable的前端分页与数据库分页

    Handsontable虽然处理速度很快,但当数据量达到10W+的时候很容易导致浏览器内存泄漏,这时候可以用分页来解决.官网提供了前端分页demo,测试后发现也只能处理低于10W的数据,而且调试的时候 ...

  7. (转)MyBatis框架的学习(二)——MyBatis架构与入门

    http://blog.csdn.net/yerenyuan_pku/article/details/71699515 MyBatis框架的架构 MyBatis框架的架构如下图: 下面作简要概述: S ...

  8. Struts2框架学习(二) Action

    Struts2框架学习(二) Action Struts2框架中的Action类是一个单独的javabean对象.不像Struts1中还要去继承HttpServlet,耦合度减小了. 1,流程 拦截器 ...

  9. 开源框架.netCore DncZeus学习(二)配置连接

    配置连接字符串,update-database,初始数据后,访问报错,提示offset错误.因为本机上使用的sql2008. .net Core 2.X中的EF访问sqlserver2008默认使用的 ...

随机推荐

  1. requests.exceptions.SSLError: hostname '127.0.0.1' doesn't match None

    http://stackoverflow.com/questions/33429453/python-requests-ssl-hostname-doesnt-match-error http://w ...

  2. socket连接和http连接的区别

    socket连接和http连接的区别 HTTP协议:简单对象访问协议,对应于应用层  ,HTTP协议是基于TCP连接的 tcp协议:    对应于传输层 ip协议:     对应于网络层 TCP/IP ...

  3. 用google mock模拟C++对象

    google mock是用来配合google test对C++项目做单元测试的.它依赖于googletest(参见我上篇文章<如何用googletest写单元测试>: http://blo ...

  4. dcmtk dcmmkdir 使用帮助

    例子: dcmmkdir --recurse  --input-directory C:\TEMP DICOM --output-file C:\TEMP\DCMDIR --recurse 递归 -- ...

  5. dedecms入侵拿webshell之方法总结

    1.注入漏洞 存在注入地址:在域名下输入plus/digg_frame.php?action=good&id=1024%651024&mid=*/eval($_POST[x]);var ...

  6. oracle 10g函数大全--数值型函数

    ABS(x) [功能]返回x的绝对值 [参数]x,数字型表达式 [返回]数字 [示例] select abs(100),abs(-100) from dual; sign(x) [功能]返回x的正负值 ...

  7. VB6.0 中 碰到 提示rs对象关闭,不允许操作, 吃一堑长一智

    VB6.0 中 碰到 提示rs对象关闭,不允许操作,  吃一堑长一智 如果碰到 这个错误提示 则请检查 你执行的每一个语句中的数据类型,包括 如果有存储过程的话,还要检查 存储过程中每一个变量和数据表 ...

  8. (转)Window 上安装Node.js

    window上安装nodejs非常的简单,next,next就行了,环境变量都是自动配置,不明白为毛java不这样 Window 上安装Node.js http://www.runoob.com/no ...

  9. Microsoft.Office.Workflow.Actions Namespace

    Microsoft.Office.Workflow.Actions Namespace SharePoint 2010   Contains the workflow activities that ...

  10. Win7如何重建桌面图标缓存

    [已解决] windows7快捷方式图标丢失的解决方案(已解决) windows7快捷方式图标丢失的解决方案转自:http://iso1.com/2010/01/14/how-to-restore-w ...