Hibernate分页设计

继续前两篇内容作个分页设计

package com.cdg.idao.impl;

import java.lang.reflect.ParameterizedType;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections;

import com.cdg.idao.IBaseDao;
import com.cdg.utils.IPage;
import com.cdg.utils.Page;

public abstract class BaseDao<M extends java.io.Serializable, PK extends java.io.Serializable>
		implements IBaseDao<M, PK> {

	private final Class<M> entityClass;

	@SuppressWarnings("unchecked")
	public BaseDao() {
		this.entityClass = (Class<M>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}

	@Autowired
	@Qualifier("sessionFactory")
	private SessionFactory sessionFactory;

	public Session getSession() {
		// 事务必须是开启的(Required),否则获取不到
		return sessionFactory.getCurrentSession();
	}

	public long countBy(Criteria criteria) {
		Number number = (Number) criteria.setProjection(Projections.rowCount())
				.uniqueResult();
		criteria.setProjection(null);// 清空函数参数
		return number.longValue();
	}

	@SuppressWarnings("unchecked")
	public List<M> limitBy(Criteria criteria, int pageSize, int pageIndex) {
		criteria.setFirstResult(pageIndex * pageSize);
		criteria.setMaxResults(pageSize);
		return criteria.list();
	}

	public IPage<M> findPageBy(Criteria criteria, int pageSize, int pageIndex) {
		long count = countBy(criteria);
		List<M> list = limitBy(criteria, pageSize, pageIndex);
		return new Page<M>(list, count, pageSize, pageIndex);
	}
}
要注意的是:计算总数必须在分页查询的前面,否则加了分页那俩个参数值后再计算分页就会出现分页计算中limit

并且分页函数计算后必须将分页Projection设置为空,否则查询分页数据就变成count函数统计了,

就这两点

IPage.java接口

import java.util.Collection;

@SuppressWarnings("unchecked")
public interface IPage<T> extends Collection {

	public abstract long getTotalSize();
	public abstract Collection<T> getData();
}

Page.java

package com.cdg.utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Page<T> implements IPage<T> {
	// 总记录数
	private long totalSize;
	// 单页显示的记录数
	private int pageSize;
	// 总页数
	private long totalPage;
	// 当前页数
	private long pageIndex;
	// 查询记录
	@SuppressWarnings("unchecked")
	private Collection<T> data;

	@SuppressWarnings("unchecked")
	public Page(Collection<T> data, long totalSize, int pageSize, int pageIndex) {
		this.data = (data != null ? data : new ArrayList<T>(0));
		this.totalSize = totalSize;
		this.pageIndex = pageIndex;
		this.pageSize = pageSize;
		this.totalPage = calcTotalPage();
	}

	public long getTotalSize() {
		return totalSize;
	}

	public int getPageSize() {
		return pageSize;
	}

	/**
	 * 求总页数
	 * 
	 * @param total
	 *            总记录数
	 * @param pageSize
	 *            单页显示的记录数
	 * @return
	 */
	public long calcTotalPage() {
		long t = getTotalSize();
		long p = getPageSize();
		if (t == 0L || p == 0L) {
			return 0L;
		}
		long r = t % p;
		long pages = (t - r) / pageSize;
		if (r > 0L) {
			pages++;
		}
		return pages;
	}

	public long getTotalPage() {
		return totalPage;
	}

	public long getCurrentPage() {
		return pageIndex;
	}

	// 哪条记录开始
	public long getPageBegin() {
		return (long) pageSize * pageIndex;
	}

	// 哪条记录结束
	public long getPageEnd() {
		return getPageBegin() + (long) getData().size();
	}

	@SuppressWarnings("unchecked")
	public Collection<T> getData() {
		return data;
	}

	public boolean isFirstPage() {
		return pageIndex == 0L;
	}

	public boolean isLastPage() {
		return pageIndex == totalPage;
	}

	@SuppressWarnings("unchecked")
	public boolean add(Object o) {
		return data.add((T) o);
	}

	@SuppressWarnings("unchecked")
	public boolean addAll(Collection c) {
		return data.addAll(c);
	}

	public void clear() {
		data.clear();
	}

	public boolean contains(Object o) {
		return data.contains(o);
	}

	@SuppressWarnings("unchecked")
	public boolean containsAll(Collection c) {
		return data.containsAll(c);
	}

	public boolean equals(Object o) {
		return data.equals(o);
	}

	public int hashCode() {
		return data.hashCode();
	}

	public boolean isEmpty() {
		return data.isEmpty();
	}

	@SuppressWarnings("unchecked")
	public Iterator iterator() {
		return data.iterator();
	}

	public boolean remove(Object o) {
		return data.remove(o);
	}

	@SuppressWarnings("unchecked")
	public boolean removeAll(Collection c) {
		return data.removeAll(c);
	}

	@SuppressWarnings("unchecked")
	public boolean retainAll(Collection c) {
		return data.retainAll(c);
	}

	public int size() {
		return data.size();
	}

	public Object[] toArray() {
		return data.toArray();
	}

	@SuppressWarnings("unchecked")
	public Object[] toArray(Object a[]) {
		return data.toArray(a);
	}
}

有一点,:返回分页中的集合要判断一下是否能查询到数据,没有要new一个长度为0的集合回去,让调用者不要当心出现空指针异常.

很多API设计最好都要考虑这一点,

业务DAO调用就这样设计

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.cdg.bean.UserModel;
import com.cdg.idao.IUserDao;
import com.cdg.utils.IPage;

@Repository("UserDao")
public class UserDao extends BaseDao<UserModel, Integer> implements IUserDao {

	@SuppressWarnings("unchecked")
	@Override
	public List<UserModel> findUserBy(UserModel user) {
		Criteria criteria = generateCriteria(user);
		return criteria.list();
	}

	public IPage<UserModel> fingPageBy(UserModel user,int pageSize, int pageIndex) {
		Criteria criteria = generateCriteria(user);
		return findPageBy(criteria, pageSize, pageIndex);
	}
	
	private Criteria generateCriteria(UserModel user){
		Criteria criteria = super.getSession().createCriteria(UserModel.class);
		if(null != user){
			if(StringUtils.isNotEmpty(user.getUsername())){
				criteria.add(Restrictions.eq("username", user.getUsername()));
			}
			if(StringUtils.isNotEmpty(user.getPassword())){
				criteria.add(Restrictions.eq("password", user.getPassword()));
			}
			if(StringUtils.isNotEmpty(user.getEmail())){
				criteria.add(Restrictions.eq("email", user.getEmail()));
			}
		}
		return criteria;
	}

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值