Hibernate(三)Criteria查询

Criteria查询是与HQL查询、原生sql查询完全不一样的查询形式,是一种对象查询。Hibernate提供了Criteria接口、Criterion接口和Restrictions类、Order类等API,用于运行时动态生成查询语句,使用起来非常简便,并且支持连缀写法。
1.条件查询

(1)使用Criteria查询需要以下步骤:
       ①使用Session接口的createCriteria()方法创建Criteria对象
      ②使用Restrictions类提供的静态方法设置查询条件,这些方法返回一个Criterion对象,表示一个查询条件,Criteria接口提供了add()方法
           来添加查询条件
      ③使用Criteria接口的list()方法执行查询

(2)下面来演示最基本的用法,没有添加任何查询条件:
  1. public static void main(String[] args) {  
  2.         Session session=HibernateUtil.currentSession();  
  3.         Transaction tx=session.beginTransaction();  
  4.           
  5.         //创建Criteria对象  
  6.         Criteria criteria=session.createCriteria(Dept.class);  
  7.         List<Dept> list=criteria.list();  
  8.         for (Dept dept : list) {  
  9.             System.out.println(dept.getDeptName()+"\t"+dept.getDeptNo());  
  10.         }  
  11.           
  12.         tx.commit();  
  13.         HibernateUtil.closeSession();  
  14.     }  
(3)查询位置在“NEW YORK”的Dept信息:
  1. //创建Criteria对象  
  2.         Criteria criteria=session.createCriteria(Dept.class);  
  3.         //添加查询条件,一个Criterion对象就是一个查询条件,这里的location是实体类中的属性名  
  4.         Criterion criterion=Restrictions.eq("location""NEW YORK");  
  5.         criteria.add(criterion);  
  6.         List<Dept> list=criteria.list();  
  7.         for (Dept dept : list) {  
  8.             System.out.println(dept.getDeptName()+"\t"+dept.getDeptNo());  
  9.         }  
(4)Hibernate提供了Restrictions类来添加查询条件,主要的方法如下:

①Criteria的比较运算
SimpleExpression Restrictions.eq(String propertyName,Object value)等于
SimpleExpression Restrictions.ne(String propertyName,Object value)不等于
SimpleExpression Restrictions.gt(String propertyName,Object value)大于
SimpleExpression Restrictions.ge(String propertyName,Object value)大于等于
SimpleExpression Restrictions.lt(String propertyName,Object value)小于
SimpleExpression Restrictions.le(String propertyName,Object value)小于等于
Criterion Restrictions.isNull(String propertyName)等于空值
Criterion Restrictions.isNotNull(String propertyName)非空值
②Criteria的范围运算

Criterion Restrictions.in(String property,Collection values)

Criterion Restrictions.in(String property,Object[] values)

等于列表

中的某一

个值


Criterion Restrictions.not(

Restrictions.in()

)

不等于列

表中任意一个值

Criterion Restrictions.between(String property,Object lo,Object hi)

大于等于值1并

且小于等于值2

Criterion  Restrictions.not(

Restrictions.between()

)

小于值1或者大于

值2

③Criteria支持的字符串模式匹配

SimpleExpression Restrictions.like(String property,Object value)

SimpleExpression Restrictions.like(String property,Objectvalue,MatchMode matchMode)

字符串模式匹配

Criterion Restrictions.ilike(String property,Object value)

Criterion Restrictions.ilike(String property,Objectvalue,MatchMode matchMode)

字符串模式匹配,同

忽略大小写时

注意:字符串匹配可以用MatchMode的静态常量来确定匹配的位置
④Criteria的逻辑运算
LogicalExpression  Restrictions.and(Criterion c1,Criterion c2)逻辑与

LogicalExpression  Restrictions.or(Criterion c1,Criterion c2)

或者

Disjunction Restrictions.disjunction()

逻辑或

LogicalExpression  Restrictions.not(Criterion expression)

逻辑非

⑤Criteria的集合运算
Criterion Restrictions.isEmpty(String propertyName)集合为空,不包含任何元素
Criterion Restrictions.isNotEmpty(String propertyName)集合不为空

2.排序
Hibernate提供了org.hibernate.criterion.Order类来对查询结果进行排序,在为Criteria对象添加排序条件的时候要使用addOrder()方法,而不再是add()方法
如:查询员工工资小于3000的员工并按照降序排序:
  1. /** 
  2.      * 1.criteria的add()方法返回的都是自身对象,所以可以通过连缀调用的方式继续添加条件; 
  3.      * 2.注意:如果实体类中的工资属性是double型的,这里的3000后要加D(或d),否则会抛出 
  4.      * 不能将Integer转换成Double类型的异常 
  5.      */  
  6.     List<Emp> list=session.createCriteria(Emp.class)  
  7.                     .add(Restrictions.lt("sal", 3000D))  
  8.                     .addOrder(Order.desc("sal"))  
  9.                     .list();  
  10.     for (Emp emp : list) {  
  11.         System.out.println(emp.getSal());  
  12.     }  
3.分页
Criteria的分页同HQL的分页用法一致,都是通过setFirstResult()和setMaxResults()方法来实现的,
uniqueResult()的用法一致,我在《 Hibernate学习(二)HQL&SQL参数绑定、投影和分页以及命名查询》中已进行解释,这里就不再过多赘述。
4.连接查询
Criteria查询和HQL都支持连接查询,但是Criteria只支持内连接和迫切左外连接查询。Criteria提供了 createCriteria()createAlias()方法来建立内连接。
例如:查询部门名称为“ACCOUNTING”并且名字中包含“l”的员工集合
①使用createCriteria()方式
  1. /** 
  2.      * 1.为了防止属性的命名冲突,在使用时尽量加上别名,如“e”和“d”; 
  3.      * 2.其中的dept是Emp实体类中拥有的属性,Emp和Dept是多对一的关系 
  4.      */  
  5.     List<Emp> list=session.createCriteria(Emp.class,"e")  
  6.                     .add(Restrictions.ilike("e.empName""l",MatchMode.ANYWHERE))  
  7.                     .createCriteria("dept""d")  
  8.                     .add(Restrictions.eq("d.deptName""ACCOUNTING"))  
  9.                     .list();  
  10.     for (Emp emp : list) {  
  11.         System.out.println(emp.getEmpName()+"\t"+emp.getDept().getDeptName());  
  12.     }  
②使用createAlias()方式
  1. List<Emp> list=session.createCriteria(Emp.class,"e")  
  2.                     .add(Restrictions.ilike("e.empName""l",MatchMode.ANYWHERE))  
  3.                     .createAlias("dept""d")  
  4.                     .add(Restrictions.eq("d.deptName""ACCOUNTING"))  
  5.                     .list();  
  6.     for (Emp emp : list) {  
  7.         System.out.println(emp.getEmpName()+"\t"+emp.getDept().getDeptName());  
  8.     }  
两种方式的使用效果是一样的,输出结果:
CLARK ACCOUNTING
MILLER ACCOUNTING

5.投影
      Hibernate提供了Projection接口和Projections类来支持Criteria查询的投影。Projections类是用来构建Projection对象的工厂类,通过调用Criteria接口的setProjection()方法来设置投影属性
(1)查询单个属性时
       如,查询部门的deptName属性
  1. /** 
  2.      * 1.setProjection()方法设置投影属性 
  3.      * 2.Property类实现了Projection接口,forName()方法制定了投影属性的名称,并返回Property对象 
  4.      */  
  5.     List<String> list=session.createCriteria(Dept.class)  
  6.                         .setProjection(Property.forName("deptName"))  
  7.                         .list();  
  8.     for (String string : list) {  
  9.         System.out.println(string);  
  10.     }  
(2)查询大于1个属性时
       当投影的属性不止一个的时候,使用Projections的projectionList()方法来设置属性名称
  1. /** 
  2.      * projetctionList()方法得到了ProjectionList对象,ProjectionList实现了Projection接口 
  3.      */  
  4.     List<Object[]> list=session.createCriteria(Dept.class)  
  5.                         .setProjection(  
  6.                                 Projections.projectionList()  
  7.                                 .add(Property.forName("deptNo"))  
  8.                                 .add(Property.forName("deptName"))  
  9.                                 )  
  10.                         .list();  
  11.     for (Object[] item : list) {  
  12.         System.out.println(item[0]+"\t"+item[1]);  
  13.     }  
(3)Projections常用的聚合查询方法
PropertyProjection Projections.groupProperty(String propertyName)分组
PropertyProjection Projections.rowCount()统计记录数
AggregateProjection Projections.avg(String propertyName)统计平均值
AggregateProjection Projections.max(String propertyName)统计最大值
AggregateProjection Projections.min(String propertyName)统计最小值
CountProjection Projections.count(String propertyName)统计某一字段的非空记录数
AggregateProjection Projections.sum(String propertyName)针对某一字段求和
Hibernate API下载点击我
6.DetachedCriteria
              Criteria接口继承了CriteriaSpecification接口,而DetachedCriteria类实现了CriteriaSpecification接口,所以两者在使用的时候类似但是两者的创建不同:
             (1)Criteria是由Session对象创建
             (2)DetachedCriteria创建的时候不需要Session对象
      那么要DetachedCriteria又是何用呢?
       在常规的web项目中,有大量的动态条件查询,程序运行时会根据用户的选择动态生成查询语句。对于分层应用来说,Web层需要传递一个查询的条件列表到业务层,业务层获得条件列表之后一次取出条件进行查询,构造查询语句。
       关键是条件列表用什么构造?如果使用Map的话,Map传递的信息时非常有限的,只能传递键值对,无法传递究竟要怎样的条件运算,所以非常有限制性。
       所以DetachedCriteria就可以解决这个问题,将所有的查询条件封装成DetachedCriteria对象,然后传递到业务层,业务层可以再Session范围内通过DetachedCriteria对象直接构造查询。

     DetachedCriteria创建时不需要Session对象,只是在执行查询(调用list()方法)的时候需要

                    如:查询查询部门名称为“ACCOUNTING”并且名字中包含“l”的员工集合

  1. /** 
  2.      * 1.使用forClass()静态方法创建对象,同样支持条件设置和连接查询 
  3.      * 2.调用list()方法之前首先使用getExecutableCriteria()方法获取Criteria对象 
  4.      */  
  5.     DetachedCriteria dCriteria=DetachedCriteria.forClass(Emp.class,"e")  
  6.                                 .createAlias("e.dept""d")  
  7.                                 .add(Restrictions.eq("d.deptName""ACCOUNTING"))  
  8.                                 .add(Restrictions.ilike("empName""l",MatchMode.ANYWHERE));  
  9.     List<Emp> list=dCriteria.getExecutableCriteria(session).list();  
  10.     for (Emp emp : list) {  
  11.         System.out.println(emp.getEmpName()+"\t"+emp.getDept().getDeptName());  
  12.     } 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值