`
lzh166
  • 浏览: 299385 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

s2sh pager-taglib分页(据用户在下拉列表选择每页显示多少行进行分页)

阅读更多
在s2sh架构中利用pager-taglib、interceptor和ThreadLocal 根据用户需求显示进行分页,在此将实现一个根据用户在下拉列表用选择每页将要显示多少行进行分页,在实现时我将数据结果集的获取与分页参数的设置独立分开,所以在我们页面请求提交到的Action类中并看不到分页参数的踪迹...
声明: pager-taglib组件默认的每页显示数目为10,相应的属性是maxPageItems="10",因此我可以将用户自己的显示行数放在session内,并将其赋值给maxPageItems就可以实现用户自己的分页类型。例如httpRequest.getSession().setAttribute("ps", 10);然后maxPageItems="ps".
关于pager-taglib标签的参数及使用请参考pager-tablib分页http://lzh166.iteye.com/blog/616715
下面开始贴代码了
首先下载pager-taglib-2.0.war ,地址http://jsptags.com/tags/navigation/pager/download.jsp,然后将lib下面的包lib下的jar包放到自己项目的lib下面。
1、实体类Organization 属性:id、name、description,在这里就不在多描述了。
2、封装类BaseService
public class BaseService extends HibernateDaoSupport {
	@Resource		//将setSessionFactory()进行重构,注入spring中的sessionFactory
	public void setSuperSessionFactory(SessionFactory sessionFactory){
		super.setSessionFactory(sessionFactory);
	}
	public List searchByPage(String hql){
		return searchByPage(hql, null);
	}
	public List searchByPage(String hql ,Object param){
		return searchByPage(hql,new Object[]{param} ,PagerContext.getOffset(), PagerContext.getPagesize());
	}
	public List searchByPage(String hql ,Object[] params){
		//查询总记录数
		String countHql = this.getCountHql(hql);
		Query query = this.getSession().createQuery(countHql);
		if(params !=null && params.length>0){
			for(int i=0;i<params.length;i++){
				query.setParameter(i, params[i]);
			}
		}
		int totals = ((Long)(query.uniqueResult())).intValue();
		
		//将总记录数放到ThreadLocal局部变量中
		PagerContext.setTotals(totals);
		//查询分页结果集数据
		query = this.getSession().createQuery(hql);
		if(params !=null && params.length>0){
			for(int i=0;i<params.length;i++){
				query.setParameter(i, params[i]);
			}
		}
		query.setFirstResult(PagerContext.getOffset());		//通过PagerContext得到offset
		query.setMaxResults(PagerContext.getPagesize());	//通过PagerContext得到pagesize

		List datas = query.list();
		return datas;
	}
	/**
	 * 根据HQL查询语句,分析得到查询总记录数的查询语句
	 * 根据HQL语句,获得查找总记录数的HQL语句如:select .... from ...
	 * 转换为:select count(*) from ....
	 * @param hql
	 * @return
	 */
	private String getCountHql(String hql){
		//取得from的位置
		int index = hql.toLowerCase().indexOf("from");
		if(index != -1){
			return "select count(*)"+ hql.substring(index);
		}
		throw new RuntimeException("无效的查询语句【"+hql+"】");
	}
}

3、业务逻辑类:orgServiceImpl
@Service("orgService")		//纳入Spring容器管理
public class OrgServiceImpl extends BaseService{
	
	public List<Organization> searchOrgs(int parentId) {
		String hql = "from Organization o where o.parent.id is null";
		if(parentId !=0){
			hql = "from Organization o where o.parent.id="+parentId;
		}
		return  this.searchByPage(hql);
	}
}

4、分页数据类:PagerContext类 利用ThreadLocal方式实现分页传值
//用于得到每页个显示数和用于查询的首记录数以及总记录数
public class PagerContext {
	//ThreadLocal 线程局部变量,就是为每一个使用该变量的线程提供一个局部的变量值的副本,每个线程都可以独立的改变该线程的变量副本,
	//而不会和其它线程的副本冲突,也就是在分页的页面中用户可以根据自己的设置任意改变每页的显示的记录数而不会影响到其他用户浏览数据显示
	private static ThreadLocal<Integer> offset = new ThreadLocal<Integer>();//用于query.setFirstResult(offset)
	private static ThreadLocal<Integer> pagesize = new ThreadLocal<Integer>();//每页显示的行数用于	query.setMaxResults(pagesize);
	
	private static ThreadLocal<Integer> totals = new ThreadLocal<Integer>();	//总记录数
	
	public static void setOffset(int value){
		offset.set(value);		//设置当前线程局部变量offset的值
	}
	public static int getOffset(){
		Integer os = (Integer)offset.get();
		if(os ==null){
			return 0;
		}
		return os;			//返回当前线程所对应的线程局部变量offset
	}
	public static void setPagesize(int value){
		pagesize.set(value);		//设置当前线程局部变量pagesize的值
	}
	public static int getPagesize(){
		Integer ps = (Integer)pagesize.get();
		if(ps == null){
			return Integer.MAX_VALUE;	//如果没有设置pagesize则显示一页
		}
		return ps;			返回当前线程所对应的线程局部变量pagesize
	}
	public static void setTotals(int value){
		ServletActionContext.getRequest().setAttribute("totals", value);
		totals.set(value);		//设置当前线程局部变量totals的值
	}
	public static int getTotals(){
		Integer ts = (Integer)totals.get();
		if(ts == null){
			return 0;
		}
		return ts;		//返回当前线程所对应的线程局部变量totals
	}
	public static void remove(){
		//将当前线程局部变量的值删除,目的是为了减少内存的占用,
		offset.remove();		//清除为每个用户分配的副本
		pagesize.remove();
		totals.remove();
	}
}

5、分页拦截器类:PagerInterceptor
public class PagerInterceptor extends AbstractInterceptor {
	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		//将请求得到的分页参数设置到ThreadLocal的局部变量中
		PagerContext.setTotals(getTotals());
		PagerContext.setOffset(getOffset());
		PagerContext.setPagesize(getPagesize());
		try {
			return invocation.invoke();
		} finally {
										//需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,
			PagerContext.remove();		//所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。						
		}
	}
	private int getTotals() {
		int totals = PagerContext.getTotals();		//从PagerContext 中取得总记录数
		return totals;			
	}
	private int getOffset(){
		int offset = 0;
		try {		//从request请求中获取当前页查询的首记录数
			offset = Integer.parseInt(ServletActionContext.getRequest().getParameter("pager.offset"));//得到标签自己计算出的pager.offset
		} catch (Exception e) {
		}
		return offset;			
	}
	private int getPagesize(){
		//从页面中请求中,获取用户设置每页显示记录数,取得pagesize参数的值
		String ps = ServletActionContext.getRequest().getParameter("pagesize");
		if(ps != null){
			try {
				Integer pagesize = Integer.parseInt(ps);
				ServletActionContext.getRequest().getSession().setAttribute("ps",pagesize);
			} catch (Exception e) {
			}
		}
		//从session中获取pagesize参数的值
		Integer pagesize = (Integer)ServletActionContext.getRequest().getSession().getAttribute("ps");
		//如果为空,则表示用户没有设置就则显示默认每页显示10行,并将其放入session,以便在显示页面赋值给maxPageItems使用
		if(pagesize == null){
			ServletActionContext.getRequest().getSession().setAttribute("ps", 10);
			return 10;
		}
		return pagesize;
	}
}

6、页面请求类:orgAction
@Controller("orgAction")
@Scope("prototype")
public class OrgAction  implements ModelDriven {
private Organization org = new Organization();	
	
	private int pid;		//父机构ID
	@Resource
	private OrgService orgService;
	/**
	 * 显示列表
	 */
	public String execute(){
		//保持父机构的父亲的ID,为返回留用
		int ppid=0;
		if(pid!=0){
			Organization o = this.orgService.find(pid);
			if(o.getParent()!=null){
				ppid = o.getParent().getId();
			}
		}
		ActionContext.getContext().put("ppid", ppid);
		//获取分页数据后,将其放到PagerModel模型中
		List<Organization> orgs = orgService.searchOrgs(pid);
		ActionContext.getContext().put("orgs", orgs);
		return "default";
	}
	public void preUpdate(int id) {
		//根据ID加载机构信息,并将信息赋值给我们的模型,
		//等待ModelDrivenInterceptor去将取出模型中的数据如不为空则压入值栈中
		//ModelDrivenInterceptor a = new ModelDrivenInterceptor();
		org = this.orgService.find(id);
	}
	public Organization getModel() {
		return org;
	}
	public Organization getOrg() {
		return org;
	}
	public int getPid() {
		return pid;
	}
	public void setPid(int pid) {
		this.pid = pid;
	}
}


7、显示页面:list.jsp 部分代码
<%@ taglib prefix="s"  uri="/struts-tags" %>
<%@ taglib prefix="pg" uri="http://jsptags.com/tags/navigation/pager"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
...
<script type="text/javascript">
function selectPagesize(field){
 document.location.href = document.all.firstpageurl.href + "&pagesize="+field.value;//得到用户从下拉列表选择的每页显示的行数,并刷新到转到首页
}
</script>
....
<s:if test="!#orgs.isEmpty">
          <s:iterator value="#orgs">
	      <tr bgcolor="#EFF3F7" class="TableBody1" onmouseover="this.bgColor = '#DEE7FF';" onmouseout="this.bgColor='#EFF3F7';">
		      <td align="center" vAlign="center"><s:property value="id"/></td>
	          <td align="center" vAlign="center"><a href="org.action?pid=<s:property value="id"/>"><s:property value="name"/></a></td>
	          <td align="center" vAlign="center"><s:property value="sn"/></td>
	          <td align="center" vAlign="center"><s:property value="parent.name"/></td>
	          <td align="center" vAlign="center"><a href="javascript:openWin('org!updateInput.action?id=<s:property value="id"/>','updateorg',600,200);">更新</a>&nbsp;
	          <a href="javascript:del('org!del.action?id=<s:property value="id"/>')">删除</a></td>
        	</tr>
        	</s:iterator>
        	</s:if>
        <!-- 在列表数据为空的时候,要显示的提示信息 -->
	    <s:else>
	    <tr>
	    	<td colspan="7" align="center" bgcolor="#EFF3F7" class="TableBody1" onmouseover="this.bgColor = '#DEE7FF';" onmouseout="this.bgColor='#EFF3F7';">
	    	没有找到相应的记录
	    	</td>
	    </tr>
	    </s:else>
.....
  <!-- 分页导航条设置 -->
<pg:pager url="org.action" items="${totals}" export="currentPageNumber=pageNumber" maxPageItems="${ps}">	<!-- ${ps}是得到session范围内的每页显示的行数 -->
		<pg:param name="pid"/>
    	<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" onchange="go(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>行

分页导航图:




  • 大小: 4.2 KB
分享到:
评论
2 楼 ageha67 2013-07-08  
如果查询的HQL是:select a.quesId, count(b.quesId) from Quertion a, QuestionItem b where a.quesId=b.quesId group by a.quesId,查2列,一列试题、一列试题有几个选项,按照你的getCountHql方法,在通过query.uniqueResult()获取总记录数的时候会提示值不唯一
1 楼 gen0304 2011-10-27  
有没有web.xml struts.xml applicationContext.xml配置?我这几天在学分页的封装,看了你的值得学习研究,能给发个项目过来最好,不胜感激  邮箱:gen0304@163.com

相关推荐

    pager-taglib 实现分页

    `pager-taglib`是一个专门用于实现分页功能的标签库,它适用于Struts 2(S2SH)框架。这个第三方组件为开发者提供了便捷的方式来实现网页的动态分页,而无需编写大量的自定义逻辑代码。 `pager-taglib`的核心在于...

    S2SH整合pager-taglibs示例

    总之,`S2SH整合pager-taglibs`的示例展示了如何在Struts2框架下利用标签库实现数据的高效分页展示,这在处理大量数据时尤为重要。通过合理的配置和代码编写,我们可以创建出用户友好、性能优秀的Web应用。在实际...

    struts2 spring hibernate所需jar包

    struts2+spring2.5+hibernate3.2整合所需的所有jar包,并额外包含了dwr.jar、分页组件pager-taglib、绘图组件jfreechart.jar、Excel解析工具包jxl.jar、数据库连接池工具包proxool.jar

    li_3ck_02a_1118.pdf

    li_3ck_02a_1118

    基于MATLAB的牛顿迭代法实现

    基于MATLAB的牛顿迭代法实现

    mellitz_3ck_01_0319.pdf

    mellitz_3ck_01_0319

    2025探索银行业人工智能驱动技术转型的投资回报率

    内容概要:文章阐述了银行采用人工智能(AI)技术替代传统系统的紧迫性和收益,讨论了通过构建现代化的数据和技术平台实现效率提升的方法,同时强调实施过程中确保数据质量和建立信任的重要性。文中提及,在金融行业中,若想优化业绩则必须拥抱AI带来的机遇,并为此进行经营模式的革新。根据Workday主办的研讨会内容,PwC金融服务风险与监管领导和Workday金融服务高层指出了大部分银行对AI认知不足的问题,强调AI在金融、人力资源以及IT等领域的广泛应用潜力及具体应用场景,如欺诈检测、技能映射和财务管理方面的作用。并且提到了AI部署过程中可能出现的技术与非技术难题及相应解决办法,鼓励金融机构及时投资建设新型基础设施,以保持竞争力。 适用人群:银行及其他金融机构管理人员;金融科技领域的专业研究人员;对企业数字化和智能化转型感兴趣的商业分析师、投资者;从事信息技术咨询工作的顾问。 使用场景及目标:本文可以帮助金融机构制定合理的技术发展战略规划,评估是否有必要推进AI技术转型,同时也为希望涉足银行科技项目的开发者提供了宝贵的市场洞察,帮助理解行业内普遍存在的困难与潜在的市场需求。此外,对于想要了解银行

    matlab程序代码项目案例论文+程序 基于在线优化的快速模型预测控制Fast model predicitive control with matlab interface.zip

    matlab程序代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    [AB PLC例程源码][MMS_043071]Phase Manager and a Scalable Batching Solution.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    [AB PLC例程源码][MMS_044386]1769-SM2 Compact I-O to DSI Module - Multi Drive Mode Operation - with.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    [AB PLC例程源码][MMS_041232]Monitor I-O Connections in Logix.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    chromedriver-linux64-136.0.7058.0.zip

    chromedriver-linux64-136.0.7058.0.zip

    [AB PLC例程源码][MMS_042504]Logix5000 interface to Atlas-Copco Tool Controller over EtherNet-IP.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    [AB PLC例程源码][MMS_042349]How to read-write data to-from a PLC using OPC in Visual Basic 6.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    电力工程领域中背压热电联产电厂的设计与参数计算

    内容概要:本文档介绍了背压热电联产(CHP)发电厂的详细设计步骤,涵盖确定各状态点的压力、温度、比焓以及质量流率的具体方法。主要内容围绕计算净电功率、燃料消耗及其效率展开,并提供了T-s图绘制的指南。针对每个组件(如蒸汽轮机、冷凝器、除氧器等),都列出了详细的效率假设和压力损失表,为实际工程应用提供了宝贵的参考资料和操作指导。同时,该作业任务要求学生从给定初始值中选择合适的操作条件进行系统模拟,并利用课程讲义和Moodle平台资料完成计算流程。 适用人群:对能源转换和动力设备设计感兴趣的学生或者初涉该领域的工程师。 使用场景及目标:旨在帮助学员深入了解并掌握背压热电联产装置的工作原理和技术指标计算的方法论,通过实践练习提高他们的问题解决能力。 其他说明:文档强调了稳态运行假设的重要性,即物质平衡等于能量输入等于输出的原则,并鼓励参与者借助附录提供的典型操作参数图表来寻找解决问题的方向。此外,它还特别指出对于一些变量值求解可能需要迭代法来进行调整,直至获得稳定结果。提交的报告必须含有一份详细的T-s图和其他必要附件。

    机器学习-市财政收入分析(含数据集)

    机器学习_市财政收入分析(含数据集)

    [AB PLC例程源码][MMS_046989]KAT with Code Sequencer.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    tracy_3cd_01_0318.pdf

    tracy_3cd_01_0318

    lusted_3cd_01_0918.pdf

    lusted_3cd_01_0918

    基于51的自动分拣系统设计20250307

    题目:基于51的自动分拣系统设计 主控:AT89C52 测距模块:超声波测距模块 甲醛传感器(ADC0832+滑动变阻器模拟) 粉尘传感器(PCF8591+滑动变阻器模拟) 净化模块(继电器驱动蓝灯) 排风模块(继电器驱动绿灯) 电源电路(5V降压为3.3V供电) 显示模块(LCD1602) 声光报警 按键(3个,切换阈值选择,阈值加减) 检测物体:开关模拟 电机驱动模块(继电器驱动直流电机转动) 功能: 1.显示屏显示甲醛,粉尘浓度可以切换设置阈值。 2.通过甲醛传感器检测车间环境,大于阈值时声光报警并启动净化模块。 3.通过粉尘传感器检测车间环境,大于阈值时声光报警并启动排风模块。 4.采用超声波传感器进行物体超高监测异常(大于XX距离)时触发声光报警 5.检测到物体(开关闭合)直流电机转动(模拟传送带)

Global site tag (gtag.js) - Google Analytics