济南网页设计|自助建站济南网站建设|聊城网站建设济南网站制作|济南网站优化 http://www.mzwkj.com www.tuanqv.com

【SSI开发总结.3】基于ibatis的自定义分页

 

分页,在web应用程序中非常常见的功能,也是最基本的功能,IBATIS本身 提供了非常傻瓜式的分页组件,但是由于其本身的原理特点,使得它是以牺牲分页效率为代价的,分层思想的确很好,但是,我们也要意识到,多一层就代表好多花 点时间执行程序流程,所以,我们又会总是尽可能的聚合功能,其实,这是一个博弈,不管怎么样,先来看下我的自定义分页吧!

我采用的方式是,在IBATIS映射中用嵌套SQL语句方式进行分页,要进行分页,我们只需要知道页面尺寸以及总记录数,然后通过视图传递的当前页 号,计算出当前页之前的记录总数,然后从大于这个之前记录总数的下一条记录开始,显示和指定页面尺寸数量相同的记录,就得到了当前页的记录

首先,为每一个POJO实体类定义一个父类PageModel,所有需要分页操作的实体都必须继承这个类,该类定义了分页所需要的相关信息

1.PageModel类

/****** PageModel.java ******/

package model;

public class PageModel {
    private int page=1;//当前页,初始为第一页
    private int pagesize;//页面尺寸
    private int pagecount;//总页面数量
    private int recordCount;//总记录数
    private int beforeCount;//页尺寸*(页数-1),当前页之前的记录总数
   
public int getBeforeCount() {
   return (page-1)*pagesize;
}
//视图中读取当前页号
public int getPage() {
   return page;
}
public void setPage(int page) {
   this.page = page;
}
//视图中读取页面尺寸
public int getPagesize() {
   return pagesize;
}
public void setPagesize(int pagesize) {
   this.pagesize = pagesize;
}
//视图中读取页面数量
public int getPagecount() {
   if(pagesize!=0)
    return (recordCount+pagesize-1)/pagesize;
   else
    return 0;
}
//视图中读取总记录数
public int getRecordCount() {
   return recordCount;
}
public void setRecordCount(int recordCount) {
   this.recordCount = recordCount;
}
}

2.定义POJO(继承PageModel)

package model;

public class Infor extends PageModel{

......................................................

}

3.配置IBATIS映射

................................................................


   <select id="recordCount" resultClass="java.lang.Integer">
      select count(*) AS [all] from infor
   </select>
   <select id="firstPage" resultClass="Infor" parameterClass="Infor">
    select top $pagesize$ * from infor order by id desc
   </select>
   <select id="otherPage" resultClass="Infor" parameterClass="Infor">
      <![CDATA[
      select top $pagesize$ * from infor
      where
      (id<(select MIN(id) from (select top $beforeCount$ id from infor order by id desc) AS T))
      order by id desc

      ]]>
   </select>

.......................................

以这种SQL语句方式分页的话,由于第一页之前的记录总数显然为0,如果只统一采用otherPage这条SQL语句分页,根据PageModel 类的定义,$beforeCount$会出现0的情况,"top 0"在SQL中是不允许的,所以我们必须把第一页的查询和其他页的查询分开写,同时,我们还必须定义一个查询总记录数的SQL语句。

显然,要实现分页,我们必须传递一个POJO对象,该对象保存了定位到当前页所需要的所有SQL语句参数

4.编写DAO类

package dao;

import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
import java.util.*;
import model.Infor;

public class InforDao extends SqlMapClientDaoSupport {
//读取所有信息数量,分页开始
    public int recordCount(){
   return Integer.parseInt(getSqlMapClientTemplate().queryForObject("infor.recordCount").toString());
    }
    public List<Infor> firstPage(Infor infor){
   return getSqlMapClientTemplate().queryForList("infor.firstPage",infor);
    }
    public List<Infor> otherPage(Infor infor){
   return getSqlMapClientTemplate().queryForList("infor.otherPage",infor);
    }
}

5.编写BO类

package bo;

import dao.InforDao;
import model.Infor;

import java.util.*;

public class InforBo {
    private InforDao dao;

public void setDao(InforDao dao) {//spring依赖注入
   this.dao = dao;
}
//读取所有信息列表
public List<Infor> getInforList(Infor infor,int pagesize,int page){
   infor.setRecordCount(dao.recordCount());
   infor.setPagesize(pagesize);
     infor.setPage(page);
   if(infor.getPage()==1)
    return dao.firstPage(infor);
   else
    return dao.otherPage(infor);
}

}

本类中,getInforList方法中,除了infor和page是必须的,pagesize为可选,普遍的我们希望页面尺寸可以在控制层自由选择,infor,page分别做为Action类的成员传递进来,为什么要这样做,看了后面action类的定义大家就明白了

6.编写ACTION类

package action;

import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
import bo.InforBo;
import model.Infor;

public class InforListAction extends ActionSupport {
private InforBo inforBo;
private List<Infor> infors;
private Infor infor;
private int page=1;

public int getPage() {
   return page;
}

public void setPage(int page) {
   this.page = page;
}

public void setInforBo(InforBo inforBo) {
   this.inforBo = inforBo;
}
public List<Infor> getInfors() {
   return infors;
}
public Infor getInfor() {
   return infor;
}
public String execute(){
   infor=new Infor();
   infors=inforBo.getInforList(infor, 20, page);
      return SUCCESS;
    }
}

至于分页标签,如“上一页”,“下一页”, 通过比如JSP标签对POJO对象的简单判断就能实现,以下是我实现的一个简单的分页标签

<s:if test="infor.page>1">

<a href="?page=1">第一页</a>

<a href="?page=<s:property value='page-1'/>">下一页</a>

</s:if>


<s:if test="infor.page<infor.pagecount">

<a href="?page=<s:property value='page+1'/>">下一页</a>

<a href="?page=<s:property value='infor.pagecount'/>">最后一页</a>

</s:if>

posted on 2009-08-20 15:49  路大侠  阅读(323)  评论(0)    收藏  举报

导航

济南户外拓展|企业户外拓展 http://www.tuanqv.com