在ssh架构中利用pager-taglib和filter根据用户需求显示进行分页,在次将实现一个根据用户在下拉类表用选择每页将要显示多少行进行分页
首先介绍pager-taglib标签:
pg:pager【这个标签用来设置分页的总体参数】重要参数说明:
url:分页的链接根地址,pager标签会在这个链接的基础上附加分页参数
items:总记录数,pager标签正是根据这个值来计算分页参数的//需要给它赋上查询的记录数
maxPageItems:每页显示的行数,默认为10
maxIndexPages:在循环输出页码的时候,最大输出多少个页码,默认是10
pg:first【第一页的标签】重要参数说明:
export变量的意义:
pageUrl - 分页链接URL地址(最重要的export参数)
pageNumber - 页码
firstItem - 首页第一行的索引值
lastItem - 首页最后一行的索引值
pg:pre【上一页标签】重要参数说明:
export变量的意义:
pageUrl - 分页链接URL地址(最重要的export参数)
pageNumber - 页码
firstItem - 前页第一行的索引值
lastItem - 前页最后一行的索引值
pg:next【下一页标签】重要参数说明:
export变量的意义:
pageUrl - 分页链接URL地址(最重要的export参数)
pageNumber - 页码
firstItem - 下页第一行的索引值
lastItem - 下页最后一行的索引值
pg:last重要参数说明:
export变量的意义:
pageUrl - 分页链接URL地址(最重要的export参数)
pageNumber - 页码
firstItem - 尾页第一行的索引值
lastItem - 尾页最后一行的索引值
pg:pages【这个标签用来循环输出页码信息】重要参数说明:
export变量的意义:
pageUrl - 分页链接URL地址(最重要的export参数)
pageNumber - 页码
firstItem - pageNumber这个页码指定的那一页的第一行的索引值
lastItem - pageNumber这个页码指定的那一页的最后一行的索引值
pager-taglib组件默认的每页显示数目为10,相应的属性是maxPageItems="10",因此我可以将用户自己的显示行数放在session内,并将其赋值给maxPageItems就可以实现用户自己的分页类型。例如httpRequest.getSession().setAttribute("ps", 10);然后maxPageItems="ps"
下面是一个具体的例子:
首先下载pager-taglib-2.0.war ,地址http://jsptags.com/tags/navigation/pager/download.jsp,然后将lib下面的包lib下的jar包放到自己项目的lib下面。
生成测试表:t_person,其中实体类Person类有id,name,phone属性,具体在hibernate配置文件中的配置略..。
创建PagerModel类用于存放从数据库查询的所有person,和总记录数。代码如下:
package com.test;
import java.util.List;
public class PagerModel {
private int total;//总记录数
private List datas;//所有用户集合
...get和set方法
}
下面一个类用于得到每页个显示数和用于查询的首记录数
package com.test.filter;
public class SystemContext {
private static ThreadLocal<Integer> offset = new ThreadLocal<Integer>();//用于query.setFirstResult(offset)
private static ThreadLocal<Integer> pagesize = new ThreadLocal<Integer>();//pagesize每页显示的行数用于
query.setMaxResults(pagesize);-----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();
}
}
主要的类PagerFilter:用于设置加载用户自定义的pagesize和offset
package com.test.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class PagerFilter implements Filter {
public static final String PAGE_SIZE_NAME = "ps";
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest)request;
//设置分页参数
SystemContext.setOffset(getOffset(httpRequest));
SystemContext.setPagesize(getPagesize(httpRequest));
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(HttpServletRequest httpRequest){
String pageSize = httpRequest.getParameter("pagesize");//得到用户自己的每页显示的行数
if(pageSize != null){
Integer ps;
try {
ps = Integer.parseInt(pageSize);
httpRequest.getSession().setAttribute(PAGE_SIZE_NAME, ps);
} catch (Exception ignore) {
}
}
Integer pagesize = (Integer)httpRequest.getSession().getAttribute(PAGE_SIZE_NAME);
if(pagesize == null){//如果用户没有设置就每日显示10行,并将其放入session供以便在显示页面赋值给maxPageItems使用
httpRequest.getSession().setAttribute(PAGE_SIZE_NAME, 10);
return 10;
}else{
return pagesize;
}
}
public void init(FilterConfig arg0) throws ServletException {
}
}
在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>
建立AbstractManager类用于封装查询数据库的细节,管理类可以通过searchPaginated(String hql)就可以得到PagerModel :
public class AbstractManager extends HibernateDaoSupport {
public PagerModel searchPaginated(String hql){
return searchPaginated(hql,offset,pagesize);
}
public PagerModel searchPaginated(String hql,int offset,int pagesize){
//获取总记录数
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 = getSession().createQuery(hql);
if(params != null && params.length > 0){
for(int i=0; i<params.length; i++){
query.setParameter(i, params[i]);
}
}
query.setFirstResult(SystemContext.getOffset());//通过SystemContext得到Offset
query.setMaxResults(SystemContext.getPagesize();//通过SystemContext得到pagesize
List datas = query.list();
PagerModel pm = new PagerModel();
pm.setDatas(datas);
pm.setTotal(total);
return pm;
} //根据HQL语句,获得查找总记录数的HQL语句如:select .... from ...转换为:select count(*) from ....
private String getCountQuery(String hql){
int index = hql.indexOf("from");
if(index != -1){
return "select count(*) " + hql.substring(index);
}
throw new SystemException("无效的HQL查询语句!");
}
}
//下面是具体管理类//得到分页数据PagerModel:
public class PersonManagerImpl extends AbstractManager implements PersonManager {//PersonManager为一个interface
public PagerModel searchPersons() {
PagerModel pm = new PagerModel();
String hql = "select p from Person p";
return this.searchPaginated(hql);
}
}
创建访问页面index.jsp
主要代码:<a href="person.do">用户分页类表</a>
相应的action页面:主要代码:
public class PersonAction extends DispatchAction {
private PersonManager personManager;//利用spring注入person管理类
@Override
protected ActionForward unspecified(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
PagerModel pm = personManager.searchPersons();
request.setAttribute("pm", pm);
return mapping.findForward("index");//通过配置文件转到list.jsp
}
public void setPersonManager(PersonManager personManager) {
this.personManager = personManager;
}
}
显示页面:list.jsp
<%@ taglib prefix="pg" uri="http://jsptags.com/tags/navigation/pager" %>//引入
...
<script type="text/javascript">
function selectPagesize(field){
document.location.href = document.all.firstpageurl.href + "&pagesize="+field.value;//得到用户从下拉列表选择的每页显示的行数,并刷新到转到首页
}
</script>
....
<table>
<!-- 列表标题栏 -->
<tr bgcolor="#EFF3F7" class="TableBody1">
<td >姓名</td>
<td >电话</td>
</tr>
<!-- 列表数据栏 -->
<c:forEach items="${pm.datas }" var="person">
<tr>
<td >${person.name }</td>
<td >${person.phone }</td>
</tr>
</c:forEach>
</table>
<TABLE>
<TBODY>
<TR>
<TD>
<!-- 分页导航条 -->
<pg:pager url="person.do" items="${pm.total}" export="currentPageNumber=pageNumber" maxPageItems="${ps}">//得到session范围内的每页显示的行数
<pg:first>
<a href="${pageUrl}" id="firstpageurl">首页</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>
<!-- 用户选择每页显示行数下拉列表 -->
每页显示
<select name="pagesize" οnchange="selectPagesize(this)" >
<c:forEach begin="5" end="50" step="5" var="i">
<option value="${i}"
<c:if test="${ps eq i }">selected</c:if>
>${i}</option>
</c:forEach>
</select>行
</TD>
</TR>
</TBODY>
</TABLE>