项目中主要是应用Hibernate3的DetachedCriteria实现分页查询,首先是写一个AbstractManager的abstract class,继承spring对hibernate的封装类org.springframework.orm.hibernate3.support.HibernateDaoSupport,覆盖getHibernateTemplate()方法,通过此方法获得一个hibernateTemplate Object,AbstractManager实例中定义好的方法最终还是去调用hibernateTamplate的方法来实现,当然我们也可以自己来实现。
在这之前我们应该先定义号这样一个记录方法返回的list的bean,代码如下:在进行此项工作的时候,要确保你的其他工作一准备就绪,比如:你的类表的映射等等。
public class PaginationSupport {
public final static int PAGESIZE = 20;
//每页显示
private int pageSize = PAGESIZE;
//取出的list
private List items;
//总页数
private int totalCount;
private int[] indexes = new int[0];
private int[] showIndexes = new int[0];
//开始也
private int startIndex = 0;
//末页
private int lastIndex = 0;
public PaginationSupport(List items, int totalCount) {
setPageSize(PAGESIZE);
setTotalCount(totalCount);
setItems(items);
setStartIndex(0);
}
public PaginationSupport(List items, int totalCount, int startIndex) {
setPageSize(PAGESIZE);
setTotalCount(totalCount);
setItems(items);
setStartIndex(startIndex);
}
public PaginationSupport(List items, int totalCount, int pageSize,
int startIndex) {
setPageSize(pageSize);
setTotalCount(totalCount);
setItems(items);
setStartIndex(startIndex);
}
public List getItems() {
return items;
}
public void setItems(List items) {
this.items = items;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
if (totalCount > 0) {
this.totalCount = totalCount;
int count = totalCount / pageSize;
if (totalCount % pageSize > 0)
count++;
indexes = new int[count];
for (int i = 0; i < count; i++) {
indexes[i] = pageSize * i;
}
setShowIndexes(count,this.startIndex);
} else {
this.totalCount = 0;
}
}
public int[] getIndexes() {
return indexes;
}
public void setIndexes(int[] indexes) {
this.indexes = indexes;
}
public int[] getShowIndexes() {
return showIndexes;
}
public void setShowIndexes(int[] showIndexes) {
this.showIndexes = showIndexes;
}
public int getStartIndex() {
return startIndex;
}
public void setStartIndex(int startIndex) {
if (totalCount <= 0)
this.startIndex = 0;
else if (startIndex >= totalCount)
this.startIndex = indexes[indexes.length - 1];
else if (startIndex < 0)
this.startIndex = 0;
else {
this.startIndex = indexes[startIndex / pageSize];
}
setShowIndexes(this.getIndexes().length,this.startIndex);
}
public int getNextIndex() {
int nextIndex = getStartIndex() + pageSize;
if (nextIndex >= totalCount)
return getStartIndex();
else
return nextIndex;
}
public int getPreviousIndex() {
int previousIndex = getStartIndex() - pageSize;
if (previousIndex < 0)
return 0;
else
return previousIndex;
}
public int getLastIndex(){
return this.indexes[this.indexes.length -1];
}
private void setShowIndexes(int totalPage,int startIndex) {
//首页 [][][][] currentPage [][][][] 末页
// add by qinyalan
if (totalPage < 3) return;
if (totalPage < 12) {
this.showIndexes = new int[totalPage-2];
for(int i=1;i<(totalPage-1);i++){
this.showIndexes[i-1] = i * pageSize;
}
return;
}
int nTempStart = pageSize;
if (startIndex > 4*pageSize) {
nTempStart = startIndex - 4 * pageSize;
}
int nTempEnd = nTempStart + 8 * pageSize;
if (nTempEnd > (totalPage -2) * pageSize){
nTempEnd = (totalPage -2) * pageSize;
nTempStart = nTempEnd - 8 * pageSize;
}
int nShowCount = (nTempEnd - nTempStart) / pageSize +1;
this.showIndexes = new int[nShowCount];
for (int i = 0; i < nShowCount; i++) {
this.showIndexes[i] = nTempStart + pageSize * i;
}
}
public static void main(String[] args){
//List items, int totalCount, int pageSize,int startIndex
PaginationSupport ps = new PaginationSupport(null,144,10,140);
/*for(int idx : ps.getIndexes()){
System.out.println(idx);
}*/
for(int idx : ps.getShowIndexes()){
System.out.println(idx);
}
}
}
AbstractManager 部分代码如下:
public abstract class AbstractManager extends HibernateDaoSupport {
public PaginationSupport findPageByCriteria(final DetachedCriteria detachedCriteria) {
return findPageByCriteria(detachedCriteria, PaginationSupport.PAGESIZE, 0);
}
public PaginationSupport findPageByCriteria(final DetachedCriteria detachedCriteria, final int startIndex) {
return findPageByCriteria(detachedCriteria, PaginationSupport.PAGESIZE, startIndex);
}
public PaginationSupport findPageByCriteria(final DetachedCriteria detachedCriteria, final int pageSize,
final int startIndex) throws HibernateException {
return (PaginationSupport) getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
int totalCount = ((Integer) criteria.setProjection(Projections.rowCount()).uniqueResult()).intValue();
criteria.setProjection(null);
List items = criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();
Iterator it = items.iterator();
try{
while (it.hasNext()){
System.out.println("it.next.class.name" + (it.next()).getClass().getName());
}
}catch(Exception e){
e.printStackTrace();
}
PaginationSupport ps = new PaginationSupport(items, totalCount, pageSize, startIndex);
return ps;
}
}, true);
}
public PaginationSupport findPageByCriteria(final DetachedCriteria criteria, final int pageSize,
final int startIndex, Order order) throws HibernateException {
DetachedCriteria clone = (DetachedCriteria) SerializationUtils.clone(criteria);
int totalCount = getCountByCriteria(clone);
if (order != null) {
criteria.addOrder(order);
}
List items = getHibernateTemplate().findByCriteria(criteria, startIndex, pageSize);
PaginationSupport ps = new PaginationSupport(items, totalCount, pageSize, startIndex);
return ps;
}
/**
* 根据 DetachedCriteria 得 到 分页结果, 运行期间会根据 criteria 自动运算总行数, 注意如果 criteria 中 set 了 Projection,
* 则返回结果 List 中为 Projection 指定类型
* @param hibernateTemplate the hibernateTemplate
* @param criteria the criteria
* @param firstResult the first result row number
* @param maxResults the max result
* @return the pagination support
* @throws org.springframework.dao.DataAccessException in case of Hibernate errors
*/
}
在DAO层调用findPageByCriteria method时记得的要继承abstract class AbstractManager ,下面是我在DAO中调用abstract class中分页方法的代码:
public class SubjectNovelDAOImpl extends AbstractManager implements SubjectNovelDAOI {
public PaginationSupport loadSubjectNovelList(int subid, int startIndex)
throws DataAccessException {
// TODO Auto-generated method stub
//select
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(A.class);
//where
detachedCriteria.add(Restrictions.eq("id", id));
detachedCriteria.add(Restrictions.not(Restrictions.eq("state", -1)));
//order by
detachedCriteria.addOrder(Order.asc("order"));
PaginationSupport ps = this.findPageByCriteria(detachedCriteria, PaginationSupport.PAGESIZE, startIndex);
return ps;
}
}
wap中要在jsp中引入模板来完成前台的展现,所以你要定义一个模板,模板中使用的没有别的,也就是一些html的一些老家伙,等等一些常用的东东,呵呵!
为保证完整性,给一个模板的示例:
<textarea id="list_templ" style="display:none">
<h2 class="bodytitlebar">
<div>
<table width="100%">
<tr><td align="left" width="80%">示例列表 </td><td align="right"><a οnclick="closeWin('("objectDIV")" style="CURSOR: pointer">关闭</a></td></tr>
</table>
</div>
</h2>
<div class="pagebodyblockbody userdefineclass">
<div class="pagebodyblockcontent">
<form name="formlist" >
<table id="listID" width="80%" border="1" cellspacing="0" cellpadding="0" >
<tr>
<th>顺序</th>
<th>示例名称</th>
<th>操作</th>
</tr>
{for n in list.items}
<tr id="item_subnovel_${n.id}" >
<td align="left">${n.snorder}</td>
<td align="center">${n.objectname.name}</td>
<td>
<a style="CURSOR: pointer" οnclick="editobject('${id}','${n.id}');"><img src="images/ico_edit.gif" alt="修改" /></a>
<a style="CURSOR: pointer" οnclick="delobject('${id}','${n.id}','${n.objectname.name}');"><img
src="images/ico_cancel.gif" alt="删除" /></a>
</td>
</tr>
{/for}
</table>
<br><br>
<!--下面的DIV块中实现了分页-->
<div>
<br><br>
共${list.totalCount}条 每页显示${list.pageSize}条 共${list.indexes.length}页<br><br>
{if list.startIndex == 0} 首页{else} <a style="CURSOR: pointer" οnclick="showobject(${id},0)">首页</a>{/if}
{for startIdx in list.showIndexes}
{var p = new Number(startIdx)/list.pageSize + 1}
{if startIdx == subnovellist.startIndex}
第${p}页
{else}
<a style="CURSOR: pointer" οnclick="showobject(${id},${startIdx})">第${p}页</a>
{/if}
{/for}
{if list.lastIndex > 0 && list.startIndex == list.lastIndex} 末页
{elseif list.lastIndex > 0 && list.startIndex <list.lastIndex}
<a style="CURSOR: pointer" οnclick="showobject(${id},${list.lastIndex})">末页</a>
{/if}
{if subnovellist.previousIndex <list.startIndex}
<a style="CURSOR: pointer" οnclick="showobject(${id},${list.previousIndex})">上一页</a> {/if}
{if list.nextIndex > list.startIndex}
<a style="CURSOR: pointer" οnclick="showobject(${id},${list.nextIndex})">下一页</a>{/if}
</div>
</form>
</div>
</div>
</textarea>
现在模板写好了,在你的.js中调用定义好的method;把list和要传下去的值送给模板:
function showobject(id,startIndex){
ajaxsubjectNovel.loadSubjectNovelList(id,startIndex,{callback:function (data){
var Object_data = {"id":id,"list" : data};
var sstext = TrimPath.processDOMTemplate("list_templ",Object_data);
showWin("objectDIV");
DWRUtil.setValue("objectDIV", sstext);
}});
}