由于项目中分页风格多样化,而分页又是项目中必不可少的,为统一项目分页风格,在上次封装的分页的组件找不到的的情况下,重新封装了一下分页组件,特意分享给大家,也防止再次丢失!
1.分页html/CSS代码及素材准备
请参考我的博客《div+css分页条》
2.分页组件实体bean类
package wilr.utils.paging.domain;
import java.io.Serializable;
import java.util.List;
/**
* @project paging
* @path wilr.utils.paging.domain
* @desc SSH版通用分页标签
* @author Wilr
* @QQ:545881075
* @time 2012-2-28 上午12:01:18
*/
public class Page implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 每页显示条数 默认显示10条
*/
private Integer pageSize = 10;
/**
* 总条数
*/
private Integer totalCount = 0;
/**
* 总页数
*/
private Integer totalPage = 0;
/**
* 当前页
*/
private Integer currentPage = 1;
/**
* 起始索引
*/
private Integer startIndex = 0;
/**
* 分页条件
*/
private String condition;
/**
* 查询的返回值
*/
private List<?> objList;
/**
* 排序
*/
private String orderBy;
/**
* 查询对象名称或表名/或查询语句
*/
private String objName;
/**
* 需要查询的字段
*/
private String queryField;
public Page(Integer totalCount,List<?> objList, Integer currentPage) {
super();
this.totalCount = totalCount;
this.objList = objList;
this.currentPage = currentPage;
}
public Page(Integer pageSize, String condition, List<?> objList,
String orderBy, String objName) {
super();
this.pageSize = pageSize;
this.condition = condition;
this.objList = objList;
this.orderBy = orderBy;
this.objName = objName;
}
public Page(Integer pageSize, String objName) {
super();
this.pageSize = pageSize;
this.objName = objName;
}
public Page(){}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getTotalCount() {
return totalCount;
}
public void setTotalCount(Integer totalCount) {
this.totalCount = totalCount;
}
public Integer getTotalPage() {
totalPage=totalCount % pageSize == 0 ? (totalCount / pageSize): (totalCount / pageSize + 1);
return totalPage;
}
public void setTotalPage(Integer totalPage) {
this.totalPage = totalPage;
}
public Integer getCurrentPage() {
return currentPage;
}
public void setCurrentPage(Integer currentPage) {
if (currentPage <= 0)
currentPage = 1;
this.currentPage = currentPage;
}
public Integer getStartIndex() {
startIndex=this.pageSize * (this.currentPage - 1);
return startIndex;
}
public void setStartIndex(Integer startIndex) {
this.startIndex =startIndex;
}
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
public List<?> getObjList() {
return objList;
}
public void setObjList(List<?> objList) {
this.objList = objList;
}
public String getOrderBy() {
return orderBy;
}
public void setOrderBy(String orderBy) {
this.orderBy = orderBy;
}
public String getObjName() {
return objName;
}
public void setObjName(String objName) {
this.objName = objName;
}
public String getQueryField() {
return queryField;
}
public void setQueryField(String queryField) {
this.queryField = queryField;
}
}
3.标签实现类
package wilr.utils.paging.taglib;
import java.io.Serializable;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import wilr.utils.paging.domain.Page;
/**
* @project paging
* @path wilr.utils.paging.taglib
* @desc 分页标签
* @author Wilr
* @QQ:545881075
* @time 2012-2-28 上午12:02:21
*/
public class PagingTag extends TagSupport implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 是否显示改变页数下拉框
*/
private boolean skipCount = true;
/**
* 是否显示跳页输入框
*/
private boolean jumpText = true;
/**
* 是否显示上/下一页按钮
*/
private boolean prevPage = true;
/**
* 是否显示首/尾页按钮
*/
private boolean startPage = true;
/**
* 是否显示遍历页
*/
private boolean forPage = true;
/**
* 是否显示当前页和总页数
*/
private boolean showCurAndSum = true;
/**
* 是否启用刷新
*/
private boolean refresh=true;
/**
* 分页实体对象
*/
private Page page;
/**
*请求URL
*/
private String url;
public boolean isSkipCount() {
return skipCount;
}
public void setSkipCount(boolean skipCount) {
this.skipCount = skipCount;
}
public boolean isJumpText() {
return jumpText;
}
public void setJumpText(boolean jumpText) {
this.jumpText = jumpText;
}
public boolean isPrevPage() {
return prevPage;
}
public void setPrevPage(boolean prevPage) {
this.prevPage = prevPage;
}
public boolean isStartPage() {
return startPage;
}
public void setStartPage(boolean startPage) {
this.startPage = startPage;
}
public boolean isForPage() {
return forPage;
}
public void setForPage(boolean forPage) {
this.forPage = forPage;
}
public boolean isShowCurAndSum() {
return showCurAndSum;
}
public void setShowCurAndSum(boolean showCurAndSum) {
this.showCurAndSum = showCurAndSum;
}
public boolean isRefresh() {
return refresh;
}
public void setRefresh(boolean refresh) {
this.refresh = refresh;
}
public Page getPage() {
return page;
}
public void setPage(Page page) {
this.page = page;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
/**
* 输出分页标签
*/
public int doStartTag() throws JspException {
try {
if(page!=null){
long currentPage=page.getCurrentPage(); //获得当前页面
long totalPage=page.getTotalPage(); //获得总页数
StringBuilder builder=new StringBuilder("<script type='text/javascript'>");
builder.append("function loadPage(pagenum){var url='"+url+"?page.currentPage='+pagenum;self.location.href=url}");
builder.append("function jumpPage(){var jumpPageNum=document.getElementById('jump_page_num').value;");
builder.append("if(jumpPageNum.length<=0){alert('请填写要跳转的页面值!');return false;}");
builder.append("if(!(/^[1-9]\\d*$/).test(jumpPageNum)){alert('跳转页面值只能填写正整数');return false;}");
builder.append("if(jumpPageNum>"+page.getTotalPage()+"){alert('跳转的页数大于总页数!');return false;}");
builder.append("var url='"+url+"?page.currentPage='+jumpPageNum;self.location.href=url }");
builder.append("function refreshPage(){self.location.href='"+url+"';}");
builder.append("</script>");
builder.append("<div class='page'><ul>");
//如果当前页面为第一页
if(currentPage==1){
if(startPage)
builder.append("<li class='start_off'></li>");
if(prevPage)
builder.append("<li class='first_off'></li>");
}
//当前页面不是第一页
else{
if(startPage)
builder.append("<li class='start' οnclick='javascript:loadPage(\"1\");'></li>");
if(prevPage)
builder.append("<li class='first' οnclick='javascript:loadPage(\""+(page.getCurrentPage()-1)+"\");'></li>");
}
//判断是否显示google风格的分页
if(forPage && totalPage>0){
builder.append("<li>");
builder.append("<div class='pagenumber'>");
builder.append("<ul>");
builder.append("<li class='fleft'></li>");
/**
* 每次只取9页
*/
for(long pagenum=1;pagenum<=page.getTotalPage();pagenum++){
if(page.getCurrentPage()<5 && pagenum<10){
if(pagenum==page.getCurrentPage())
builder.append("<li class='nowPage' title='第"+pagenum+"页'>"+pagenum+"</li>");
else
builder.append("<li class='fcenter' title='第"+pagenum+"页'><a href='"+url+"?page.currentPage="+pagenum+"'>"+pagenum+"</a></li>");
}else{
//页面大于5以后,当前页位于中间
if(pagenum>page.getCurrentPage()-5 && pagenum<page.getCurrentPage()+5){
if(pagenum==page.getCurrentPage())
builder.append("<li class='nowPage' title='第"+pagenum+"页'>"+pagenum+"</li>");
else
builder.append("<li class='fcenter' title='第"+pagenum+"页'><a href='"+url+"?page.currentPage="+pagenum+"'>"+pagenum+"</a></li>");
}
}
}
builder.append("<li class='fright'></li>");
builder.append("</ul>");
builder.append("</div>");
builder.append("</li>");
}
//如果当前页面为尾页
if(currentPage==totalPage || totalPage<=0){
if(prevPage)
builder.append("<li class='next_off'></li>");
if(startPage)
builder.append("<li class='end_off'></li>");
}
//当前页面不是尾页
else{
if(prevPage)
builder.append("<li class='next' οnclick='javascript:loadPage(\""+(page.getCurrentPage()+1)+"\");'></li>");
if(startPage)
builder.append("<li class='end' οnclick='javascript:loadPage(\""+page.getTotalPage()+"\");'></li>");
}
/* 先屏蔽
//如果启用页面显示页数选择 这里启用5 10 15 20供用户选择
if(skipCount){
builder.append("<li>");
builder.append("<select class='rounded' name='page.pageSize'");
builder.append("<option value='5'>5条/页</option>");
builder.append("<option value='10' selected='selected'>10条/页</option>");
builder.append("<option value='15'>15条/页</option>");
builder.append("<option value='20'>20条/页</option>");
builder.append("</select>");
builder.append("</li>");
}*/
//如果启用页面跳转
if(jumpText && totalPage>0){
builder.append("<li>");
builder.append("<input type='text' size='5' name='page.currentPage' id='jump_page_num' class='rounded jumpInput'>");
builder.append("</li>");
builder.append("<li class='jump' οnclick='javascript:jumpPage();'></li>");
}
//如启用总页数显示
if(showCurAndSum){
builder.append("<li class='pageInfo'>共<span>"+page.getTotalCount()+"</span>条/共<span>"+page.getTotalPage()+"</span>页</li>");
}
if(refresh){
builder.append("<li class='refresh' title='刷新' οnclick='javascript:refreshPage();'></li>");
}
builder.append("</ul></div>");
super.pageContext.getOut().print(builder.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
return SKIP_BODY;
}
}
4.标签配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>w</short-name>
<uri>http://wilr.iteye.com</uri>
<display-name>分页通用标签</display-name>
<tag>
<name>p</name>
<tag-class>wilr.utils.paging.taglib.PagingTag</tag-class>
<attribute>
<name>skipCount</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
<description>是否显示条数选择</description>
</attribute>
<attribute>
<name>jumpText</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
<description>是否显示跳页输入</description>
</attribute>
<attribute>
<name>prevPage</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
<description>是否显示上/下一页</description>
</attribute>
<attribute>
<name>startPage</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
<description>是否显示首/尾页</description>
</attribute>
<attribute>
<name>forPage</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
<description>是否使用循环输出页</description>
</attribute>
<attribute>
<name>showCurAndSum</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
<description>是否显示总页/总条数</description>
</attribute>
<attribute>
<name>refresh</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
<description>是否可以刷新</description>
</attribute>
<attribute>
<name>url</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>String</type>
<description>请求URL</description>
</attribute>
<attribute>
<name>page</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<description>分页对象</description>
</attribute>
</tag>
</taglib>
5.分页数据持久层实例工厂
package wilr.utils.paging.factory;
import wilr.utils.paging.domain.Page;
/**
* @project paging
* @path wilr.utils.paging.factory
* @desc 分页组件接口工厂
* @author Wilr
* @QQ:545881075
* @time 2012-2-29 上午10:08:16
*/
public interface PagingFactory {
/**
* @project paging
* @path wilr.utils.paging.factory
* @desc 查询对象条数
* @author Wilr
* @QQ:545881075
* @time 2012-2-29 上午10:08:49
* @param page 分页对象
* @return
*/
public Integer queryObjCount(Page page);
/**
* @project paging
* @path wilr.utils.paging.factory
* @desc 查询对象
* @author Wilr
* @QQ:545881075
* @time 2012-2-29 上午10:08:49
* @param page 分页对象
* @return
*/
public Page queryObjList(Page page);
}
6.分页组件持久层实例工厂实现类(这里采用Spring注解方式,有需求的朋友可以自己修改)
package wilr.utils.paging.factory.impl;
import javax.annotation.Resource;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import wilr.utils.paging.domain.Page;
import wilr.utils.paging.factory.PagingFactory;
@Service
@Transactional
public class PagingFactoryImpl implements PagingFactory {
@Resource SessionFactory factory;
@Transactional(propagation=Propagation.NOT_SUPPORTED)
public Integer queryObjCount(Page page) {
StringBuffer queryHQL=new StringBuffer("SELECT COUNT(*) FROM "+page.getObjName());
//如果查询条件不为空
if(page.getCondition()!=null && !page.getCondition().trim().equals(""))
queryHQL.append(" WHERE "+page.getCondition());
//如果排序不为空
if(page.getOrderBy()!=null && !page.getOrderBy().trim().equals(""))
queryHQL.append(" order by "+page.getOrderBy());
return Integer.parseInt(factory.getCurrentSession().createQuery(queryHQL.toString()).uniqueResult().toString());
}
@Transactional(propagation=Propagation.NOT_SUPPORTED)
public Page queryObjList(Page page) {
StringBuffer queryHQL=new StringBuffer();
if(page.getQueryField()!=null && !page.getQueryField().trim().equals(""))
queryHQL.append("SELECT "+page.getQueryField()+" FROM "+page.getObjName());
else
queryHQL.append("FROM "+page.getObjName());
if(page.getCondition()!=null && !page.getCondition().trim().equals(""))
queryHQL.append(" WHERE "+page.getCondition());
if(page.getOrderBy()!=null)
queryHQL.append(" order by "+page.getOrderBy());
System.out.println(queryHQL.toString());
Query query=factory.getCurrentSession().createQuery(queryHQL.toString());
query.setFirstResult(page.getStartIndex());
query.setMaxResults(page.getPageSize());
page.setTotalCount(this.queryObjCount(page));
page.setObjList(query.list());
return page;
}
}
7.Service或Action使用Demo
7.1 注入分页数据持久层工厂
@Resource PagingFactory factory;
7.2 声明分页主键实体对象Page并get set
private Page page;
public Page getPage() {return page;}
public void setPage(Page page) {this.page = page;}
7.3 方法调用
if(page==null)page=new Page();
//对象名称
page.setObjName("Demo t");
//条件
page.setCondition("t.id>0");
//排序
page.setOrderBy("t.id desc");
//每页显示条数(默认10)
page.setPageSize(15);
//查询属性(为空查询所有)
page.setQueryField("t.id,t.name');
//调用工厂获得数据
page=factory.queryObjList(page);
8.页面使用(css相关可参考第1条查看我的博客获得)
8.1 引入标签
<%@ taglib prefix="w" uri="http://wilr.iteye.com"%>
8.2 引入CSS
<link rel="stylesheet" type="text/css" href="${path}/paging/paging.css">
8.3 使用标签
<w:p url="${path}/test!loadDemoList.action" page="${page}"></w:p>
8.3页面调用数据
<s:if test="page.objList==null || page.objList.size==0">
无信息!
</s:if>
<s:else>
<s:iterator value="page.objList" id="demo">
${demo.id}--${demo.name}
</s:iterator>
</s:else>
需要JSON数据可在Action中如下处理:
JSONArray.fromObject(page.getObjList());
标签全部结束,将工厂、实体、标签打包,以后就可以通用。呵呵!!!!欢迎大家交流和提出宝贵的意见
!!!
附:标签参数说明:
必选参数
url:查询列表的action访问路径。
page:分页对象。从actiong中得到。
可选参数:
forPage:是否显示多页风格(类似google),值:true/false 默认为:true
jumpText:是否可以输入跳转页,值:true/false 默认为:true
prevPage:是否显示上/下一页,值:true/false 默认为:true
prevPage:是否显示上/下一页,值:true/false 默认为:true
startPage:是否显示首/尾页,值:true/false 默认为:true
showCurAndSum:是否显示总条数和总页数,值:true/false 默认为:true
refresh:是否启用刷新,值:true/false 默认为 true