`

JSP分页标签

阅读更多
最近在学习Struts的标签,结合以前做过的一些小项目,把分页写成了一个标签,做得不是非常的完美,还有很多不足,比如在最后一页显示记录数为6条,这个时候如果改变pageSize,查询出的结果会是空的。。。
先说说自己的分页思路吧:
首先是一个标签处理类,里面有上一页,下一页的连接,以及跳转到第几页,和一个下拉列表用来选择每页显示记录数目,首先它会根据当前页来判断上一页下一页是不是应该显示,
当点击这些连接的时候会触发一个onchange或者是onclick事件,设置一页页面的隐藏表单值,然后提交表单让Action或者是Servlet对应的方法来处理,还有就是当前分页信息会被放在一个PageInfor的实体Bean中,这个Bean会放到Session当中,供Action以及模型层数据调用。。。
先贴一下自己的代码吧:
首先是,分页标签处理类:
package tags;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

import model.Page;
/*
 * 功能:一个JSP分页标签,可以向这个JSP标签传递的属性有
 * 1.rowCount:通过查询数据库得到,每次必须都是最新的啊,因为数据表里的数据不断变化,这个属性是必须的,在TLD中要设置required为true;
 * 要特别注意的就是这个rowCount,应该是带查询条件的记录数目。否则查询后如果总记录数有100条,而查询出的只有一条,它还会显示下一页。。。
 * 在这里,我是在查询数据库的时候把它查询出来的,然后设置在pageInfor里面。
 * 
 * 2.pageCount:通过计算得到,由于rowCount的不断变化,它也是不断变化的啊
 * 3.pageSize:初始值设为10
 * 4.pageNow:当前页,被保存在一个PageInfor的Bean当中,这个Bean放在缓存当中.这个属性也是必须要设置的。
 * 5,action_pageIndex方法名,这个最好是不要写在里面,从外面传入方法名,有利于重用。。。
 * 
 */
public class PageTag extends TagSupport {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	//一共多少条记录数,这个属性必须要传入
	private int rowCount=0;
	//当前页
	private int pageNow=1;
	//总共多少页
	private int pageCount;
	//每页多少条记录数
	private int pageSize=10;
	
	//数据库表名,
	private String tablename="";
	//要传入Action层的方法名称,由表现层直接传入,而不是在标签里面写死,更好的重用性。
	private String action_pageIndex="";
	
	private String action_pageSize="doPageSize";
	public int getPageCount() {
		return pageCount;
	}
	public void setPageCount(int pageCount) {
		this.pageCount = pageCount;
	}
	public int getPageNow() {
		return pageNow;
	}
	public void setPageNow(int pageNow) {
		this.pageNow = pageNow;
	}
	public int getPageSize() {
		return pageSize;
	}
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
	public int getRowCount() {
		return rowCount;
	}
	public void setRowCount(int rowCount) {
		this.rowCount = rowCount;
	}
	@Override
	public int doStartTag() throws JspException {
		JspWriter out=pageContext.getOut();
		//每次都要计算当前时刻的pageCount,因为rowCount是从pageInfor里面取得的,而pageInfor里面
		//的rowCount是从数据库中查询到得最新的数据条数。。
		int state = rowCount % pageSize;
		System.out.println("RowCOunt==========="+this.rowCount);
		System.out.println("PageSize============"+this.pageSize);
		if (state != 0) {
			pageCount = rowCount / pageSize + 1;
		} else {
			pageCount = rowCount / pageSize;
		}

		if (pageCount <= 0) {
			pageCount = 1;
		}
		StringBuffer result=new StringBuffer();
		int prePage=pageNow-1;
		int nextPage=pageNow+1;
		if(prePage>0){
			//传递给JS三个参数,第一个是方法名称,第二个是查询页,第三格式页面大小
			result.append("<a href=# onclick=doPostBack('"+this.action_pageIndex+"','"+prePage+"','"+this.pageSize+"')>");
			result.append("上一页");
			result.append("</a>");
		}else{
			result.append("上一页  ");
		}
		if(nextPage<=this.pageCount){
			result.append("<a href=# onclick=doPostBack('"+this.action_pageIndex+"','"+nextPage+"','"+this.pageSize+"')>");
			result.append("下一页");
			result.append("</a>第");
		}else{
			result.append("下一页  第");
		}
		result.append("<input type='text' size=2 name='pageGoto' id='txtPageIndex' onchange=doPostBack('"+this.action_pageIndex+"',$F(txtPageIndex),'"+this.pageSize+"')>页");
		result.append("									<select onchange=doPostBack('"+this.action_pageIndex+"','"+this.pageNow+"',this.value)>");
		result.append("									<option value='10'");
		if(pageSize==10){
			//注意要有空格,否则可能会连起来
			result.append(" selected");
		}
		result.append(		">10条记录</option>");
		result.append("									<option value='15'");
		if(pageSize==15){
			//注意要有空格,否则可能会连起来
			result.append(" selected");
		}
		result.append(		">15条记录</option>");
		result.append("									<option value='20'");
		if(pageSize==20){
			//注意要有空格,否则可能会连起来
			result.append(" selected");
		}
		result.append(		">20条记录</option>");
		result.append("</select>");
		result.append("<input type='button' value='Goto' onclick='doPostBack('"+this.action_pageIndex+"',$F(txtPageIndex),'"+this.pageSize+"')'>");
		try {
			out.write(result.toString());
		} catch (IOException e) {
			System.out.println("在标签处理类输出的时候出现异常");
			e.printStackTrace();
		}
		return this.EVAL_BODY_INCLUDE;
	}
	@Override
	public int doEndTag() throws JspException {
		return this.EVAL_PAGE;
	}
	public String getAction_pageIndex() {
		return action_pageIndex;
	}
	public void setAction_pageIndex(String action_pageIndex) {
		this.action_pageIndex = action_pageIndex;
	}
	public String getAction_pageSize() {
		return action_pageSize;
	}
	public void setAction_pageSize(String action_pageSize) {
		this.action_pageSize = action_pageSize;
	}
}


标签约束文件page.tld:
<tag>
    	<name>page</name>
    	<tag-class>tags.PageTag</tag-class>
    	<body-content>empty</body-content>
    	<attribute>
    		<name>pageCount</name>
    		<required>false</required>
    		<rtexprvalue>true</rtexprvalue>
    	</attribute>
    	<attribute>
    		<name>rowCount</name>
    		<required>true</required>
    		<rtexprvalue>true</rtexprvalue>
    	</attribute>
    	<attribute>
    		<name>pageSize</name>
    		<required>false</required>
    		<rtexprvalue>true</rtexprvalue>
    	</attribute>
    	<attribute>
    		<name>pageNow</name>
    		<required>true</required>
    		<rtexprvalue>true</rtexprvalue>
    	</attribute>
    	<attribute>
    		<name>action_pageIndex</name>
    		<required>true</required>
    		<rtexprvalue>true</rtexprvalue>
    	</attribute>
    </tag>

在web.xml当中进行一下配置:
<taglib>
  	<taglib-uri>/WEB-INF/tld/page.tld</taglib-uri>
 	<taglib-location>/WEB-INF/tld/page.tld</taglib-location> </taglib>

这样就可以在JSP页面当中进行引用了啊。
还有就是一个pageInfor Bean,用来记录用户当前页,分页大小,查询条件等操作,这个实体Bean会被放到Session当中,供各个类进行调用。
PageInfor代码:
package tags;

import java.util.HashMap;
import java.util.Map;
import model.StockDao;
/*
 * 为了保持可重用性,在这个类当中不能有任何关于表信息的代码,表明其实也应该放到外面去。。。
 * 比如rowCount,这个我们肯定是要通过set方法传给它的,然后再保存到session
 * 当中去。
 */
public class PageInfor {
	//表示当前页
	private int pageNow=1;
	//一共多少条记录,需要查询数据库得到
	private int rowCount=0;
	//计算得到总页数
	private int pageCount=1;
	//每页显示的记录数
	private int pageSize=10;
	//按照哪个字段进行排序
	private String sortBy="stockid";
	//按照升序还是降序进行排序,默认是升序
	private String sortType="asc";
	//当前业中的查询关键词
	private Map keyWords=new HashMap();
	//数据库表名
	private String tablename;
	public String getTablename() {
		return tablename;
	}

	public void setTablename(String tablename) {
		this.tablename = tablename;
	}

	//构造函数,完成初始化
	public PageInfor(){
		this.pageNow=1;
		this.sortType="asc";
	}

	public Map getKeyWords() {
		return keyWords;
	}

	public void setKeyWords(Map keyWords) {
		this.keyWords = keyWords;
	}

	public int getPageCount() {
		return pageCount;
	}

	public void setPageCount(int pageCount) {
		int i=this.rowCount%this.pageSize;
		if(i==0){
			this.pageCount=this.rowCount/this.pageSize;
		}else{
			this.pageCount=this.rowCount/this.pageSize+1;
		}
	}

	public int getPageNow() {
		return pageNow;
	}

	public void setPageNow(int pageNow) {
		this.pageNow = pageNow;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getRowCount() {
		return rowCount;
	}

	public void setRowCount(int rowCount) {
		this.rowCount = rowCount;
	}

	public String getSortBy() {
		return sortBy;
	}

	public void setSortBy(String sortBy) {
		this.sortBy = sortBy;
	}

	public String getSortType() {
		return sortType;
	}

	public void setSortType(String sortType) {
		this.sortType = sortType;
	}
}


最后就是模型层的分页方法了,写得不是很好,见谅啊各位。
public static List getPageNow(PageInfor pageInfor){
		int pageNow=pageInfor.getPageNow();
		int pageSize=pageInfor.getPageSize();
		String sortBy=pageInfor.getSortBy();
		String sortType=pageInfor.getSortType();
		Map keyWords=pageInfor.getKeyWords();
		List list=new ArrayList();
		//貌似这条sql语句也挺好用,select * from stock where stockid not in(select stockid from stock where rownum<pageSize*(pageNow-1)) and rowNum<pageSize;
		//这里有个诡异的地方是,我把表明替换成?用占位符来表示的时候,提示表明无效,只好用这个原始的方法了,嗨。。。
		String sql="SELECT * FROM (SELECT A.*, ROWNUM RN FROM (SELECT * FROM "+pageInfor.getTablename()+" where 1=1";
		if(null!=keyWords){
			Set set=keyWords.keySet();
			Iterator iterator=set.iterator();
			while(iterator.hasNext()){
				String key=iterator.next().toString();
				System.out.println("key========="+key);
				String value=keyWords.get(key).toString();
				sql+=" and "+key+" = "+value;
			}
			
		}
		//下面这句是用来查询当前查询条件下的总记录数目
		try {String sql1=sql+")A)";
		System.out.println("sdfsdf:"+sql1);
			int rowCount=0;
			ps=conn.prepareStatement(sql1);
			rst=ps.executeQuery();
			while(rst.next()){
				rowCount++;
			}
			pageInfor.setRowCount(rowCount);
		} catch (SQLException e) {
			e.printStackTrace();
			logger.error("------>getPageNow(PageInfor pageInfor),在查询总记录数的时候出现异常" +
					"出错信息是:"+e.getMessage());
		}
		
		sql+=" ) A WHERE ROWNUM <=? )WHERE RN >= ?";
		System.out.println("sql============"+sql);
//		String sql="select * from stock where stockid not in(select stockid from stock where rownum<=?) and rownum<=?";
		try {
			ps=conn.prepareStatement(sql);
			ps.setInt(1, pageSize*pageNow);
			ps.setInt(2,(pageNow-1)*pageSize+1);
			rst=ps.executeQuery();
			while(rst.next()){
				StockBean sb=new StockBean();
				sb.setStockid(rst.getString("stockid"));
				sb.setWareid(rst.getString("wareid"));
//				sb.setWarename(rst.getString("warename"));
				sb.setStockdate(rst.getDate("stockdate"));
				sb.setMoneysum(rst.getInt("moneysum"));
				sb.setOperator(rst.getString("operator"));
				sb.setStockamount(rst.getInt("stockamount"));
				list.add(sb);
			}
		} catch (SQLException e2) {
			e2.printStackTrace();
			logger.error("在查询分页的时候出现异常,出错信息是:"+e2.getMessage());
		}
		
		return list;
	}


分享到:
评论
1 楼 norrain 2010-07-01  
    

相关推荐

    非常好用的jsp分页标签

    可以直接将JAR包导入后就可以使用的JSP分页标签, 对JSP+SERVLET非常适合,适用于WEB开发,如果有不会用的可以进行询问。

    jsp分页标签 分页标记

    分页标记。网页开发中经常遇到查询,当记录多时需要分页显示,通过上一页、下一页浏览全部记录。通常的处理方法比较烦,特别是需要在页面中传递查询参数的表单,比较繁烦,当对记录进行操作时,往往要临时转到其它...

    带有多种样式的JSP分页标签

    带有多种样式的JSP分页标签,内附多种样式,方便使用,只需一句标签即可实现多样式分页

    自定义JSP分页标签

    很适用的自定义JSP分页标签,完整的源码.在实际项目中,是经常用到的.讲解一下:自定义分页标签实现步骤--1.编写一个分页标签处理类;2.配置标记的tld;3.web.xml配置;4.jsp页面调用标记.顺便补充一下:分页,有真分页(读...

    jsp分页标签JPage(HOT)

    本人写的jsp分页标签(JPage) JPage包括两种样式: 一种为原始的上一页下一页 一种样式类似百度 本人Email: jiaoer840214@163.com

    jsp分页标签

    jsp分页标签详细解说

    jsp分页标签,servlet技术实现

    jsp分页集成标签,使用简单,方便。压缩包里有使用说明

    JSP分页标签,超级好用,非常灵活

    这是JSP分页标签。使用,请参照说明书。有不懂的请发邮件给我16663755@qq.com

    JSP分页标签,方便JSP开发

    用于方便JSP分页开发 可用CSS设置标签输出的样式,也可通过标签直接设置标签输出的样式。

    jsp自定义分页标签

    自己写的jsp分页标签jar包,包含tld配置文件,用的话导入就可以直接使用。

    JSP分页标签(最新)

    自己开发的JSP界面分页标签,解决了当前分页代码的繁琐性,只需要导入此jar包即可使用,具体使用方法参照readme.txt文件内容

    jsp分页标签源代码

    包含java源代码,js源代码,jsp示例代码。

    JSP自定义分页标签

    JSP自定义分页标签,mysql数据库,通过导入jar包,使用标签的方式实现分页的功能。

    jsp分页标签库

    使用taglib自定义标签进行分页,包含jar包等一些信息

    根据Ecside ET 源码改变WEB JSP 分页标签

    很好很实用的jsp 分页插件 支持导出Excel PDF等实用功能,允许直接更改编辑分页 插入数据库中 利用jQuery AJAX技术 很实用欢迎下载

    Jsp分页标签<authorization-module>

    authorization-module,标签实现包,在jsp开发项目中能轻松实现分页.无需自己手动写类.此包已经封装过. 只需在页面调用标签就OK了

    pager-taglib分页标签

    jsp 分页标签。 用于列表自动分页功能

Global site tag (gtag.js) - Google Analytics