继续前两篇内容作个分页设计
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;
}
}