Hibernate Criteria查询之多表连接分页-2【分页封装】

分页相关实体类:

分页信息类:

package org.accp.mhouse.pager;

import java.io.Serializable;
import java.util.List;

/**分页信息类
 * 封装分页条件和结果
 * */
public class PageInfo<T> implements Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -4026351129192551762L;


	/*条件部分*/
	private Class<T> classzz;
	

	private int pageSize = 10;
	private int pageIndex = 1;
	
	private java.util.List<Condition> conditions = new java.util.ArrayList<Condition>();
	private java.util.List<Order> orders = new java.util.ArrayList<Order>();
	private java.util.List<Fetch> fetchs = new java.util.ArrayList<Fetch>();
	
	public java.util.List<Fetch> getFetchs() {
		return fetchs;
	}
	public void setFetchs(java.util.List<Fetch> fetchs) {
		this.fetchs = fetchs;
	}
	
	
	/*分页结果部分*/
	private int recordCount;
	private int pageCount;
	private java.util.List<T> result;
	public Class<T> getClasszz() {
		return classzz;
	}
	public void setClasszz(Class<T> classzz) {
		this.classzz = classzz;
	}
	public int getPageSize() {
		return pageSize;
	}
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
	public int getPageIndex() {
		return pageIndex;
	}
	public void setPageIndex(int pageIndex) {
		this.pageIndex = pageIndex;
	}
	public java.util.List<Condition> getConditions() {
		return conditions;
	}
	public void setConditions(java.util.List<Condition> conditions) {
		this.conditions = conditions;
	}
	public java.util.List<Order> getOrders() {
		return orders;
	}
	public void setOrders(java.util.List<Order> orders) {
		this.orders = orders;
	}
	public int getRecordCount() {
		return recordCount;
	}
	public void setRecordCount(int recordCount) {
		this.recordCount = recordCount;
	}
	public int getPageCount() {
		return pageCount;
	}
	public void setPageCount(int pageCount) {
		this.pageCount = pageCount;
	}
	public java.util.List<T> getResult() {
		return result;
	}
	public void setResult(java.util.List<T> result) {
		this.result = result;
	}
	public PageInfo(Class<T> classzz, int pageSize, int pageIndex,
			List<Condition> conditions, List<Order> orders) {
		super();
		this.classzz = classzz;
		this.pageSize = pageSize;
		this.pageIndex = pageIndex;
		this.conditions = conditions;
		this.orders = orders;
	}
	public PageInfo(Class<T> classzz) {
		super();
		this.classzz = classzz;
	}
	
	
	
	

}


分页信息类中涉及的其它类:

筛选条件类:

package org.accp.mhouse.pager;

import java.io.Serializable;

/**筛选条件类*/
public class Condition implements Serializable {
	
	private String propertyName;
	
	private Compare cp = Compare.EQ;
	
	private Object propertyValue;

	public String getPropertyName() {
		return propertyName;
	}

	public void setPropertyName(String propertyName) {
		this.propertyName = propertyName;
	}

	public Compare getCp() {
		return cp;
	}

	public void setCp(Compare cp) {
		this.cp = cp;
	}

	public Object getPropertyValue() {
		return propertyValue;
	}

	public void setPropertyValue(Object propertyValue) {
		this.propertyValue = propertyValue;
	}

	public Condition(String propertyName, Compare cp, Object propertyValue) {
		super();
		this.propertyName = propertyName;
		this.cp = cp;
		this.propertyValue = propertyValue;
	}

	public Condition() {
		super();
	}
	
	

}


多表连接抓取策略类:

package org.accp.mhouse.pager;

import java.io.Serializable;

/**多表连接抓取策略类*/
public class Fetch implements Serializable {
	
	/**属性名*/
	private String fetchPropertyName;
	/**别名*/
	private String aliasName;
	/**抓取方式*/
	private FetchMode fetchMode = FetchMode.INNER_JOIN;
	
	public FetchMode getFetchMode() {
		return fetchMode;
	}
	public void setFetchMode(FetchMode fetchMode) {
		this.fetchMode = fetchMode;
	}
	public String getFetchPropertyName() {
		return fetchPropertyName;
	}
	public void setFetchPropertyName(String fetchPropertyName) {
		this.fetchPropertyName = fetchPropertyName;
	}
	public String getAliasName() {
		return aliasName;
	}
	public void setAliasName(String aliasName) {
		this.aliasName = aliasName;
	}
	public Fetch(String fetchPropertyName, String aliasName) {
		super();
		this.fetchPropertyName = fetchPropertyName;
		this.aliasName = aliasName;
	}
	public Fetch() {
		super();
	}
	public Fetch(String fetchPropertyName, String aliasName, FetchMode fetchMode) {
		super();
		this.fetchPropertyName = fetchPropertyName;
		this.aliasName = aliasName;
		this.fetchMode = fetchMode;
	}
	
	
	
	

}


排序类:

package org.accp.mhouse.pager;

import java.io.Serializable;

/**排序*/
public class Order implements Serializable {
	
	private String propertyName;
	private Direct direct = Direct.ASC;
	
	public String getPropertyName() {
		return propertyName;
	}
	public void setPropertyName(String propertyName) {
		this.propertyName = propertyName;
	}
	public Direct getDirect() {
		return direct;
	}
	public void setDirect(Direct direct) {
		this.direct = direct;
	}
	public Order(String propertyName, Direct direct) {
		super();
		this.propertyName = propertyName;
		this.direct = direct;
	}
	public Order() {
		super();
	}
	public Order(String propertyName) {
		super();
		this.propertyName = propertyName;
	}
	
	
	
	

}


以上类中用到的一些枚举类型:

条件比较操作枚举:

package org.accp.mhouse.pager;

/**条件比较操作符【时间关系没有封装完】*/
public enum Compare {
	
	EQ,
	GT,
	LT,
	GE,
	LE,
	NE,
	LIKE

}


排序方式:

package org.accp.mhouse.pager;

/**排序方式*/
public enum Direct {
	
	ASC,
	DESC

}


抓取模式枚举:

package org.accp.mhouse.pager;

/**抓取模式*/
public enum FetchMode {
	
	/**内连接*/
	INNER_JOIN,
	/**左外连接*/
	LEFT_JOIN

}


分页重点实现代码:

package org.accp.mhouse.dao.hbimpl;

import java.io.Serializable;
import java.util.List;

import org.accp.mhouse.dao.HibernateSessionFactory;
import org.accp.mhouse.dao.IHibernateCallback;
import org.accp.mhouse.pager.Condition;
import org.accp.mhouse.pager.Direct;
import org.accp.mhouse.pager.Fetch;
import org.accp.mhouse.pager.Order;
import org.accp.mhouse.pager.PageInfo;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.ResultTransformer;

@SuppressWarnings("unchecked")
public class CommonDao<T extends Serializable> {
	
	private Class<T> classzz;
	
	public CommonDao() {
		// TODO Auto-generated constructor stub
	}
	
	public CommonDao(Class<T> classzz) {
		// TODO Auto-generated constructor stub
		this.classzz = classzz;
	}
	
	/**分页方法*/
	public void pager(final PageInfo pi){
		if (pi==null || pi.getClasszz()==null){
			throw new RuntimeException("分页基本条件不全");
		}
		
		execute(new IHibernateCallback() {
			
			@Override
			public Object doInHibernate(Session session) {
				Criteria qbc = session.createCriteria(pi.getClasszz());
				
				//0.处理抓取策略
				prepareFetch(qbc,pi.getFetchs());
				
				//1.设置条件
				List<Condition> list = pi.getConditions();
				
				prepareCondition(qbc,list.toArray(new Condition[]{}));
				
				//2.计算总条数
				qbc.setProjection(Projections.rowCount());
				pi.setRecordCount(
						(Integer)qbc.uniqueResult()
				);
				//3.总页数
				pi.setPageCount(
						pi.getRecordCount()%pi.getPageSize()==0?
								pi.getRecordCount()/pi.getPageSize():
									pi.getRecordCount()/pi.getPageSize()+1
				);
				//4.清空投影查询的设置
				qbc.setProjection(null);
				qbc.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
				//5.处理排序
				prepareOrder(qbc,((List<Order>)pi.getOrders()).toArray(new Order[]{}));			

							
				//6.获得分页结果
				pi.setResult(
						qbc
							.setFirstResult((pi.getPageIndex()-1)*pi.getPageSize())
							.setMaxResults(pi.getPageSize())
							.list()
				);
				return null;
			}
		});		
	}
	
	/**处理分页条件*/
	private void prepareCondition(Criteria qbc,Condition...conditions){
		if (conditions==null || conditions.length==0)
			return;
		
		for (Condition cdt : conditions) {
			switch (cdt.getCp()) {
			case EQ:
				qbc.add(Restrictions.eq(cdt.getPropertyName(), cdt.getPropertyValue()));
				break;					
			case GT:
				qbc.add(Restrictions.gt(cdt.getPropertyName(), cdt.getPropertyValue()));
				break;					
			case LT:
				qbc.add(Restrictions.lt(cdt.getPropertyName(), cdt.getPropertyValue()));
				break;
			case GE:
				qbc.add(Restrictions.ge(cdt.getPropertyName(), cdt.getPropertyValue()));
				break;
			case LE:
				qbc.add(Restrictions.le(cdt.getPropertyName(), cdt.getPropertyValue()));
				break;
			case LIKE:
				qbc.add(Restrictions.like(cdt.getPropertyName(), cdt.getPropertyValue().toString(), MatchMode.ANYWHERE));
				break;
			default:
				break;
			}
		}
	}
	/**处理排序*/
	private void prepareOrder(Criteria qbc,Order...orders){
		
		if (orders==null || orders.length==0)
			return;
		
		for (Order ord : orders) {
			qbc.addOrder(
					ord.getDirect()==Direct.ASC?
							org.hibernate.criterion.Order.asc(ord.getPropertyName()):
								org.hibernate.criterion.Order.desc(ord.getPropertyName())
				);
		}
	}
	
	/**处理抓取策略*/
	private void prepareFetch(Criteria qbc,java.util.List<Fetch> fetchList){
		if (fetchList==null)
			return;
		for (Fetch fetch : fetchList) {
			if (null!=fetch.getAliasName() && !"".equals(fetch.getAliasName())){				
				qbc.createAlias(
						fetch.getFetchPropertyName(), 
						fetch.getAliasName(), 
						fetch.getFetchMode()==org.accp.mhouse.pager.FetchMode.INNER_JOIN?CriteriaSpecification.INNER_JOIN:CriteriaSpecification.LEFT_JOIN
				);				
			}
		}
	}
	
	/**通过回调执行任何Hibernate操作*/
	public Object execute(IHibernateCallback hibernateCallback){
		Session session = null;
		Transaction ts = null;
		Object result = null;
		try {
			session = HibernateSessionFactory.getSession();
			ts = session.beginTransaction();
			
			if (hibernateCallback!=null)
				result = hibernateCallback.doInHibernate(session);
			
			ts.commit();
		} catch(Exception e){
			ts.rollback();
			throw new RuntimeException(e.getMessage());
		} finally {
			if (session!=null) session.close();
		}
		
		return result;
	}
	
	/**多条件查询*/
	public List<T> findByProperties(Condition...conditions){
		if (conditions==null || conditions.length==0){
			return findAll();
		}
		
		Session session = null;
		try {
			session = HibernateSessionFactory.getSession();
			Criteria qbc = session.createCriteria(classzz);
			prepareCondition(qbc,conditions);
			return qbc.list();
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage());
		} finally {
			if (session!=null) session.close();
		}
	}
}


 测试代码:

public static void main(String[] args) {
		
		CommonDao<House> cdao = new CommonDao<House>();
		PageInfo<House> pi = new PageInfo<House>(House.class);
		pi.getFetchs().add(new Fetch("street", "st"));
		pi.getFetchs().add(new Fetch("st.district","d"));
		pi.getFetchs().add(new Fetch("users","u"));
		pi.getFetchs().add(new Fetch("type","t"));
		pi.getConditions().add(new Condition("d.name", Compare.EQ, "青羊区"));
		pi.getOrders().add(new Order("id", Direct.ASC));
		
		cdao.pager(pi);
		
		System.out.printf("共%d条 %d页 当前第%d页\n",pi.getRecordCount(),pi.getPageCount(),pi.getPageIndex());
		for (House h : pi.getResult()) {
			System.out.println(h.getTitle()+"\t\t"+
					h.getStreet().getName()+"\t\t"+
					h.getStreet().getDistrict().getName()+"\t\t"+
					h.getUsers().getName()+"\t\t"+
					h.getType().getName()
			);
		}
	}


控制台输出:

Hibernate: 
    select
        count(*) as y0_ 
    from
        house.house this_ 
    inner join
        house.street st1_ 
            on this_.street_id=st1_.ID 
    inner join
        house.district d2_ 
            on st1_.district_id=d2_.ID 
    inner join
        house.type t4_ 
            on this_.type_id=t4_.ID 
    inner join
        house.users u3_ 
            on this_.user_id=u3_.id 
    where
        d2_.name=?
Hibernate: 
    select
        this_.ID as ID2_4_,
        this_.contact as contact2_4_,
        this_.description as descript3_2_4_,
        this_.floorage as floorage2_4_,
        this_.price as price2_4_,
        this_.pubdate as pubdate2_4_,
        this_.street_id as street8_2_4_,
        this_.title as title2_4_,
        this_.type_id as type9_2_4_,
        this_.user_id as user10_2_4_,
        st1_.ID as ID1_0_,
        st1_.district_id as district3_1_0_,
        st1_.name as name1_0_,
        d2_.ID as ID4_1_,
        d2_.name as name4_1_,
        t4_.ID as ID3_2_,
        t4_.name as name3_2_,
        u3_.id as id0_3_,
        u3_.idAdmin as idAdmin0_3_,
        u3_.name as name0_3_,
        u3_.password as password0_3_,
        u3_.telephone as telephone0_3_,
        u3_.userName as userName0_3_ 
    from
        house.house this_ 
    inner join
        house.street st1_ 
            on this_.street_id=st1_.ID 
    inner join
        house.district d2_ 
            on st1_.district_id=d2_.ID 
    inner join
        house.type t4_ 
            on this_.type_id=t4_.ID 
    inner join
        house.users u3_ 
            on this_.user_id=u3_.id 
    where
        d2_.name=? 
    order by
        this_.ID asc limit ?
共6条 1页 当前第1页
第一个房子  东南路  青羊区  admin  一室一厅
第七间房  东南路  青羊区  luo  两室一厅
wrwegrhtrhgh  东南路  青羊区  admin  四室一厅
gfdgggggggggggggg  东南路  青羊区  admin  两室一厅
dfegggg  东南路  青羊区  admin  两室一厅
rrrrr  知春路  青羊区  zhang  两室一厅
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值