hibernate系列十七:Criteria查询

         Criteria查询是Hibernate提供的另一种查询方式,与HQL基于字符串的查询形式完全不同。Hibernate提供了org.Hibernate.Criteria接口、org.hibernate.criterion.Criterion接口和org.hibernate.criterion .Restrictions类等Criteria API,用于支持在运行时动态生成查询语句。

1.  条件查询

使用Criteria查询包括以下步骤:

    (1)使用Session接口的createCriteria()方法创建Criteria对象。

    (2)使用Restrictions类提供的静态方法设置查询条件,这些静态方法返回Criterion对象,一个Criterion对象代表一个查询条件。Criteria接口的add()方法用来添加查询条件。

    (3)使用Criteria接口的list()方法执行查询语句,list()方法返回java.util.List类型的结果,List集合中的每个元素都是持久化对象。

    接下来通过示例来说明。

案例1  查询男学生

package com.obtk.test;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class CriteraTest1 {
	public static void main(String[] args) {
		Session session=null;
		try {
			session=HiberUtil.getSession();
			Criteria cri=session.createCriteria(StudentEntity.class);
			cri=cri.add(Restrictions.eq("gender", "男"));
			List<StudentEntity> stuList=cri.list();
			for(StudentEntity stu : stuList){
				System.out.println(stu.getStuId()+"\t"+stu.getStuName()+"\t"+stu.getGender());
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}

案例2  多条件查询,链式编程

package com.obtk.test;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class CriteraTest2 {
	public static void main(String[] args) {
		Session session=null;
		try {
			session=HiberUtil.getSession();
			//添加条件,链式编程
			Criteria cri=session.createCriteria(StudentEntity.class)
						.add(Restrictions.eq("gender", "男"))
						.add(Restrictions.ge("age", 20))
						.add(Restrictions.le("age", 26))
						.add(Restrictions.isNotNull("dept"));
			List<StudentEntity> stuList=cri.list();
			for(StudentEntity stu : stuList){
				System.out.println(stu.getStuId()+"\t"+stu.getStuName()+"\t"+stu.getGender());
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}


案例3   范围查询

package com.obtk.test;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class CriteraTest3 {
	public static void main(String[] args) {
		Session session=null;
		try {
			session=HiberUtil.getSession();
			//范围查询
			//String[] theValues={"男","妖"};
			//添加条件,链式编程
			Criteria cri=session.createCriteria(StudentEntity.class)
						//.add(Restrictions.in("gender", theValues));
						.add(Restrictions.between("age", 20, 26));
			List<StudentEntity> stuList=cri.list();
			for(StudentEntity stu : stuList){
				System.out.println(stu.getStuId()+"\t"+stu.getStuName()
						+"\t"+stu.getGender()+"\t"+stu.getAge());
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}

案例4   模糊查询

package com.obtk.test;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class CriteraTest4 {
	public static void main(String[] args) {
		Session session=null;
		try {
			session=HiberUtil.getSession();
			//模糊查询
			Criteria cri=session.createCriteria(StudentEntity.class)
						.add(Restrictions.like("stuName", "发", MatchMode.END));
			List<StudentEntity> stuList=cri.list();
			for(StudentEntity stu : stuList){
				System.out.println(stu.getStuId()+"\t"+stu.getStuName()
						+"\t"+stu.getGender()+"\t"+stu.getAge());
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}

案例5  非空查询

package com.obtk.test;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

import com.obtk.entitys.DeptEntity;
import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class CriteraTest5 {
	public static void main(String[] args) {
		Session session=null;
		try {
			session=HiberUtil.getSession();
			//非空查询
			Criteria cri=session.createCriteria(DeptEntity.class)
						.add(Restrictions.isNotEmpty("stuList"));
			List<DeptEntity> stuList=cri.list();
			for(DeptEntity stu : stuList){
				System.out.println(stu.getDeptId()+"\t"+stu.getDepartName());
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}

2.  动态条件查询

    在HQL语句里面我们介绍了使用HQL实现动态查询,下面介绍使用Criteria实现动态查询。请自行对比二者的使用的优缺点。

==========条件实体类ConditionEnity=========================

package com.obtk.entitys;

public class ConditionEnity {
	private String stuName;
	private String gender;
	private Integer minAge;
	private Integer maxAge;
	
	public ConditionEnity() {
	}
	public ConditionEnity(String stuName, String gender, Integer minAge,
			Integer maxAge) {
		super();
		this.stuName = stuName;
		this.gender = gender;
		this.minAge = minAge;
		this.maxAge = maxAge;
	}
	public String getStuName() {
		return stuName;
	}
	public void setStuName(String stuName) {
		this.stuName = stuName;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public Integer getMinAge() {
		return minAge;
	}
	public void setMinAge(Integer minAge) {
		this.minAge = minAge;
	}
	public Integer getMaxAge() {
		return maxAge;
	}
	public void setMaxAge(Integer maxAge) {
		this.maxAge = maxAge;
	}
	
	
}
================ConditionQuery.java====================
package com.obtk.test;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

import com.obtk.entitys.ConditionEnity;
import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class ConditionQuery {
	
	public static void queryByCon(ConditionEnity con){
		Session session=null;
		try {
			session=HiberUtil.getSession();
			Criteria cri=session.createCriteria(StudentEntity.class);
			if(con.getStuName()!=null){
				cri.add(Restrictions.like("stuName", con.getStuName(),MatchMode.ANYWHERE));
			}
			if(con.getGender()!=null){
				cri.add(Restrictions.eq("gender",con.getGender()));
			}
			if(con.getMinAge()!=null){
				cri.add(Restrictions.ge("age",con.getMinAge()));
			}
			if(con.getMaxAge()!=null){
				cri.add(Restrictions.le("age",con.getMaxAge()));
			}
			List<StudentEntity> stuList=cri.list();
			for(StudentEntity stu : stuList){
				System.out.println(stu.getStuName()+"\t"+stu.getGender()+"\t"+stu.getAge());
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
	public static void main(String[] args) {
		//是在servlet和action里面完成
		ConditionEnity con=new ConditionEnity("张", "男", null, 26);
		queryByCon(con);
	}
}

3  排序,唯一查询,分页查询

案例1   唯一查询

package com.obtk.test;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.obtk.entitys.ConditionEnity;
import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class CountTest {
	public static void main(String[] args) {
		Session session=null;
		try {
			session=HiberUtil.getSession();
			Criteria cri=session.createCriteria(StudentEntity.class);
			//查多少行数据
			cri.setProjection(Projections.count("stuId"));
			Integer count=(Integer)cri.uniqueResult();
			System.out.println("总条数:"+count);
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}
案例2  排序及分页

package com.obtk.test;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;

import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class PageQuery {
	static int getTotalRows(){
		Session session=null;
		Integer count=0;
		try {
			session=HiberUtil.getSession();
			Criteria cri=session.createCriteria(StudentEntity.class);
			//查多少行数据
			cri.setProjection(Projections.count("stuId"));
			count=(Integer)cri.uniqueResult();
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
		return count;
	}
	static void queryPage(Integer pageNo,Integer pageSize){
		Session session=null;
		try {
			session=HiberUtil.getSession();
			Criteria cri=session.createCriteria(StudentEntity.class);
			cri.addOrder(Order.desc("age"));  //排序
			cri.setFirstResult((pageNo-1)*pageSize);  //设置从哪一条数据开始
			cri.setMaxResults(pageSize); //设置每页显示多少条
			List<StudentEntity> stuList=cri.list();
			System.out.println("总条数:"+getTotalRows());
			for(StudentEntity stu : stuList){
				System.out.println(stu.getStuId()+"\t"+stu.getStuName()
						+"\t"+stu.getGender()+"\t"+stu.getAge());
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
	public static void main(String[] args) {
		queryPage(2,3);
	}
}

4.   连接查询

案例1  内关联

package com.obtk.test;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.obtk.entitys.DeptEntity;
import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class JoinTest {
	public static void main(String[] args) {
		Session session=null;
		try {
			session=HiberUtil.getSession();
			Criteria cri=session.createCriteria(StudentEntity.class,"s")
						.createAlias("s.dept", "d")
						.add(Restrictions.eq("d.departName", "计算机系"))
						.add(Restrictions.like("s.stuName", "张", MatchMode.ANYWHERE));
			List<StudentEntity> stuList=cri.list();
			for(StudentEntity stu : stuList){
				System.out.println(stu.getStuId()+"\t"+stu.getStuName()+"\t"+stu.getGender()
						+"\t"+stu.getDept().getDepartName());
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}

5.  投影及分组查询

案例1  投影

package com.obtk.test;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;

import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class GroupTest1 {
	public static void main(String[] args) {
		Session session=null;
		try {
			session=HiberUtil.getSession();
			Criteria cri=session.createCriteria(StudentEntity.class)
			       .setProjection(Projections.projectionList()
			    		   .add(Property.forName("stuName"))
			    		   .add(Property.forName("gender")));
			List<Object[]> rows=cri.list();
			for(Object[] row : rows){
				System.out.println(row[0]+"\t"+row[1]);
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}

案例2   分组

package com.obtk.test;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;

import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class GroupTest2 {
	public static void main(String[] args) {
		Session session=null;
		try {
			session=HiberUtil.getSession();
			Criteria cri=session.createCriteria(StudentEntity.class,"s")
					.createAlias("s.dept", "d")
			       .setProjection(Projections.projectionList()
			    		   //指明分组的列
			    		   .add(Projections.groupProperty("d.departName")) 
			    		   .add(Projections.min("s.age"))
			    		   .add(Projections.avg("s.age"))
			    		   .add(Projections.max("s.age"))
			    		   );
			List<Object[]> rows=cri.list();
			for(Object[] row : rows){
				System.out.println(row[0]+"\t"+row[1]+"\t"+row[2]+"\t"+row[3]);
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}


6  使用DetachedCriteria

     DetachedCriteria类和Criteria接口功能类似,它们分别实现和继承了CriteriaSpecification接口。Criteria与DetachedCriteria均可使用Criterion与Projection设置查询条件,但两者的创建形式不同。

(1)Criteria是由Session对象创建的。

(2)DetachedCriteria创建时不需要Session对象。

 Hibernate支持DetachedCriteria这是一个非常有意义的特性。如下应用场景可以考虑使用DetacbedCriteria查询:在常规的Web编程中,有大量的动态条件查询,即用户在网页上自由选择某些条件,程序根据用户的选择条件,动态生成SQL语句,进行查询。针对这种需求,对于分层应用程序来说,Web层需要传递一个查询的条件列表给业务层对象,业务层对象获得这个条件列表之后,依次取出条件,构造查询语句。

 这里的难点是条件列表用什么来构造。传统上使用Map,但是Map传递的信息非常有限,只能传递name和value,无法传递究竟要做怎样的条件运算,究竟进行大于、小于,还是like等操作,业务层对象必须确切掌握所有的隐含条件才能判断。因此,一旦隐含条件改变,业务层对象的查询构造算法必须相应修改。但是这种查询条件的改变是隐式约定的,不是程序代码约束的,因此,非常容易出错。

    DetachedCriteria可以解决这个问题,即在Web层,程序员使用DetachedCriteria来构造查询条件,然后将DetachedCriteria作为方法调用参数传递给业务层对象。业务层对象获得DetachedCriteria后,可以在Session范围内直接构造Criteria进行查询。到此为止,查询语句的构造完全被搬离到Web层实现,两业务层则与查询条件构造完全解耦。

案例1  

package com.obtk.test;

import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;

import com.obtk.entitys.StudentEntity;
import com.obtk.utils.HiberUtil;

public class DetachTest {
	public static void main(String[] args) {
		try {
			//方便web分层处理,解耦
			DetachedCriteria dech=DetachedCriteria.forClass(StudentEntity.class,"s")
				.createAlias("s.dept", "d")
				.add(Restrictions.like("s.stuName", "张", MatchMode.ANYWHERE))
				.add(Restrictions.eq("s.gender", "男"))
				.add(Restrictions.eq("d.departName", "计算机系"));
			List<StudentEntity> stuList=dech.getExecutableCriteria(HiberUtil.getSession())
								.list();
			for(StudentEntity stu : stuList){
				System.out.println(stu.getStuId()+"\t"+stu.getStuName()+"\t"+stu.getGender()
						+"\t"+stu.getDept().getDepartName());
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		}finally{
			HiberUtil.closeSession();
		}
	}
}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

御前两把刀刀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值