最近在学习Struts的标签,结合以前做过的一些小项目,把分页写成了一个标签,做得不是非常的完美,还有很多不足,比如在最后一页显示记录数为6条,这个时候如果改变pageSize,查询出的结果会是空的。。。
先说说自己的分页思路吧:
首先是一个标签处理类,里面有上一页,下一页的连接,以及跳转到第几页,和一个下拉列表用来选择每页显示记录数目,首先它会根据当前页来判断上一页下一页是不是应该显示,
当点击这些连接的时候会触发一个onchange或者是onclick事件,设置一页页面的隐藏表单值,然后提交表单让Action或者是Servlet对应的方法来处理,还有就是当前分页信息会被放在一个PageInfor的实体Bean中,这个Bean会放到Session当中,供Action以及模型层数据调用。。。
先贴一下自己的代码吧:
首先是,分页标签处理类:
标签约束文件page.tld:
在web.xml当中进行一下配置:
这样就可以在JSP页面当中进行引用了啊。
还有就是一个pageInfor Bean,用来记录用户当前页,分页大小,查询条件等操作,这个实体Bean会被放到Session当中,供各个类进行调用。
PageInfor代码:
最后就是模型层的分页方法了,写得不是很好,见谅啊各位。
先说说自己的分页思路吧:
首先是一个标签处理类,里面有上一页,下一页的连接,以及跳转到第几页,和一个下拉列表用来选择每页显示记录数目,首先它会根据当前页来判断上一页下一页是不是应该显示,
当点击这些连接的时候会触发一个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;
}