Hibernate 中Criteria Query查询详解
当查询数据时,人们往往需要设置查询条件。在SQL或HQL语句中,查询条件常常放在where子句中。此外,Hibernate还支持Criteria查询(Criteria Query),这种查询方式把查询条件封装为一个Criteria对象。在实际应用中,使用Session的createCriteria()方法构建一个org.hibernate.Criteria实例,然后把具体的查询条件通过Criteria的add()方法加入到Criteria实例中。这样,程序员可以不使用SQL甚至HQL的情况下进行数据查询,如例程9-1所示。
例程9-1 Criteria应用实例
代码
Criteria cr = session.createCriteria(Student.class); //生成一个Criteria对象
cr.add(Restrictions.eq("name", "Bill"));//等价于where name=’Bill’
List list = cr.list();
Student stu = (Student)list.get(0);
System.out.println(stu.getName());
1.常用的查询限制方法
在例程9-1中,Restrictions.eq()方法表示equal,即等于的情况。Restrictions类提供了查询限制机制。它提供了许多方法,以实现查询限制。这些方法及其他一些criteria常用查询限制方法列于表9-1中。
表9-1 Criteria Query常用的查询限制方法
方 法 |
说 明 |
Restrictions.eq() |
equal,= |
Restrictions.allEq() |
参数为Map对象,使用key/value进行多个等于的对比,相当于多个Restrictions.eq()的效果 |
Restrictions.gt() |
greater-than, > |
Restrictions.lt() |
less-than, < |
Restrictions.le() |
less-equal, <= |
Restrictions.between() |
对应SQL的between子句 |
Restrictions.like() |
对应SQL的like子句 |
Restrictions.in() |
对应SQL的in子句 |
Restrictions.and() |
and关系 |
Restrictions.or() |
or关系 |
Restrictions.isNull() |
判断属性是否为空,为空返回true,否则返回false |
Restrictions.isNotNull() |
与Restrictions.isNull()相反 |
Order.asc() |
根据传入的字段进行升序排序 |
Order.desc() |
根据传入的字段进行降序排序 |
MatchMode.EXACT |
字符串精确匹配,相当于“like 'value'” |
MatchMode.ANYWHERE |
字符串在中间位置,相当于“like '%value%'” |
MatchMode.START |
字符串在最前面的位置,相当于“like 'value%'” |
MatchMode.END |
字符串在最后面的位置,相当于“like '%value'” |
例1:查询学生名字以t开头的所有Student对象。
Criteria cr = session.createCriteria(Student.class); cr.add(Restrictions.like(“name”, “t%”)) List list = cr.list(); Student stu = (Student)list.get(0); |
或者使用另一种方式:
Criteria cr = session.createCriteria(Student.class); cr.add(Restrictions.like(“name”, “t”, MatchMode.START)) List list = cr.list(); Student stu = (Student)list.get(0); |
例2:查询学生姓名在Bill, Jack和Tom之间的所有Student对象。
String[] names = {“Bill”, “Jack”, “Tom”} Criteria cr = session.createCriteria(Student.class); cr.add(Restrictions.in(“name”, names)) List list = cr.list(); Student stu = (Student)list.get(0); |
例3:查询学生的年龄age等于22或age为空(null)的所有Student对象。
Criteria cr = session.createCriteria(Student.class); cr.add(Restrictions.eq(“age”, new Integer(22)); cr.add(Restrictions.isNull(“age”)); List list = cr.list(); Student stu = (Student)list.get(0); |
例4:查询学生姓名以字母F开头的所有Student对象,并按姓名升序排序。
Criteria cr = session.createCriteria(Student.class); cr.add(Restrictions.like(“name”, “F%”); cr.addOrder(Order.asc(“name”)); List list = cr.list(); Student stu = (Student)list.get(0); |
调用Order.asc的方法应是Criteria的addOrder()方法。
使用add()方法加入条件时,预设是使用and来组合条件,如果要用or的方式来组合条件,则可以使用Restrictions.or()方法,例如结合age等于(eq)20或(or)age为空(isNull)的条件:
- Criteria criteria = session.createCriteria(User.class);
- criteria.add(Restrictions.or(
- Restrictions.eq("age", new Integer(20)),
- Restrictions.isNull("age")
- ));
- List users = criteria.list();
观察所产生的SQL语句,将使用where与or子句完成SQL的条件查询:
Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where (this_.age=? or this_.age is null)
使用Criteria进行查询时,不仅仅能组合出SQL中where子句的功能,还可以组合出如排序、统计、分组等的查询功能。这就是Criteria进阶查询。
排序
您可以使用Criteria进行查询,并使用org.hibernate.criterion.Order对结果进行排序,例如使用Oder.asc(),指定根据”age”由小到大排序(反之则使用desc()):
- Criteria criteria = session.createCriteria(User.class);
- criteria.addOrder(Order.asc("age"));
- List users = criteria.list();
注意在加入Order条件时,使用的是addOrder()方法,而不是add()方法,在产生SQL语句时,会使用order by与asc(desc)来进行排序指定:
Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ order by this_.age asc
限定查询笔数
Criteria的setMaxResults()方法可以限定查询回来的笔数,如果配合setFirstResult()设定传回查询结果第一笔资料的位置,就可以实现简单的分页,例如传回第51笔之后的50笔资料(如果有的话):
- Criteria criteria = session.createCriteria(User.class);
- criteria.setFirstResult(51);
- criteria.setMaxResults(50);
- List users = criteria.list();
根据您所指定得资料库,Hibernate将自动产生与资料库相依的限定笔数查询子句,例如在MySQL中,将使用limit产生以下的SQL语句:
Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ limit ?, ?
统计动作
您可以对查询结果进行统计动作,使用 org.hibernate.criterion.Projections的avg()、rowCount()、count()、max()、min ()、 countDistinct()等方法,再搭配Criteria的setProjection()方法加入条件设定,例如对查询结果的"age"作平均:
- Criteria criteria = session.createCriteria(User.class);
- criteria.setProjection(Projections.avg("age"));
- List users = criteria.list();
上面的程式将由Hibernate自动产生SQL的avg函数进行平均计算:
Hibernate: select avg(this_.age) as y0_ from T_USER this_
分组
还可以配合Projections的groupProperty()来对结果进行分组,例如以"age"进行分组,也就是如果资料中"age"如果有 20、20、25、30,则以下会显示20、25、30:
- Criteria criteria = session.createCriteria(User.class);
- criteria.setProjection(Projections.groupProperty("age"));
- List users = criteria.list();
上面的程式将由Hibernate自动产生SQL的group by子句进行分组计算:
Hibernate: select this_.age as y0_ from T_USER this_ group by this_.age
如果想同时结合统计与分组功能,则可以使用org.hibernate.criterion.ProjectionList,例如下面的程式会计算每个年龄各有多少个人:
- ProjectionList projectionList = Projections.projectionList();
- projectionList.add(Projections.groupProperty("age"));
- projectionList.add(Projections.rowCount());
- Criteria criteria = session.createCriteria(User.class);
- criteria.setProjection(projectionList);
- List users = criteria.list();
观察所产生的SQL语句,将使用group by先进行分组,再针对每个分组进行count函数的计数,
Hibernate: select this_.age as y0_, count(*) as y1_ from T_USER this_ group by this_.age
根据已知物件进行查询
设定查询条件并非一定要使用Restrictions,如果属性条件很多,使用Restrictions也不方便,如果有一个已知的物件,则可以根据这个物件作为查询的依据,看看是否有属性与之类似的物件,例如:
- User user = new User();
- user.setAge(new Integer(30));
- Criteria criteria = session.createCriteria(User.class);
- criteria.add(Example.create(user));
- List users = criteria.list();
Criteria进阶查询中,您可以透过 org.hibernate.criterion.Example的create()方法来建立Example实例,Example实作了 Criteria介面,因此可以使用add()方法加入至Criteria条件设定之中,Hibernate将自动过滤掉空属性,根据已知物件上已设定的属性,判定是否产生于where子句之中:
Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where (this_.age=?)
设定SQL范本
如果您了解如何撰写SQL语句,想要设定一些Hibernate产生SQL时的范本,您也可以使用Restrictions的sqlRestriction()方法,提供SQL语法范本作限定查询,例如查询name以cater开头的资料:
- Criteria criteria = session.createCriteria(User.class);
- criteria.add(Restrictions.sqlRestriction(
- "{alias}.name LIKE (?)", "cater%", Hibernate.STRING));
- List users = criteria.list();
其中alias将被替换为与User类别相关的名称,而? 将被替换为cater%,也就是第二个参数所提供的值,sqlRestriction()方法第一个参数所设定的是where子句的部份,所以在SQL撰写时,不必再写where,观察所产生的SQL语句,将使用您所设定的SQL范本作为基础,来完成SQL的条件查询:
Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where this_.name LIKE (?)
如果有多个查询条件,例如between子句的查询,则可以如下:
- Criteria criteria = session.createCriteria(User.class);
- Integer[] ages = {new Integer(20), new Integer(40)};
- Type[] types = {Hibernate.INTEGER, Hibernate.INTEGER};
- criteria.add(Restrictions.sqlRestriction(
- "{alias}.age BETWEEN (?) AND (?)", ages, types));
- List users = criteria.list();
观察所产生的SQL语句如下:
Hibernate: select this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ from T_USER this_ where this_.age BETWEEN (?) AND (?)
2.连接限制
在Criteria 查询中使用FetchMode来实现连接限制。在HQL语句中,可以通过fetch关键字来表示预先抓取(Eager fetching),如下所示:
from Group g left join fetch g.students s where g.name like ' 05' |
可以使用Criteria的API完成同样的功能,如下所示:
Criteria cr = session.createCriteria(Group.class); cr.setFetchMode(“students”, FetchMode.EAGER); cr.add(Restrictions.like(“name”, “2005”, MatchMode.END)) List list = cr.list(); |
以上两种方式编写的代码,都使用相同的SQL语句完成它们的功能,如下所示:
select g.*, s.* from Group g left outer join Student s on g.id = s.group_id where g.name like ' 05' |
);
Hibernate 中Criteria Query查询详解相关推荐
- java+criteriaquery_Hibernate 中Criteria Query查询详解【转】
当查询数据时,人们往往需要设置查询条件.在SQL或HQL语句中,查询条件常常放在where子句中.此外,Hibernate还支持Criteria查询(Criteria Query),这种查询方式把查询 ...
- hibernate中List一对多映射关系详解
场景:一个Team对一个多个Student,其中Team中的studes属性为List类型 直接上代码,测试通过的: Team.java Java代码 package com.fgh.hibernat ...
- Hibernate中的QBC查询方式详解
Hibernate中的QBC查询方式详解 QBC:Query By Criteria,条件查询. 是一种更加面向对象化的查询的方式. 1.QBC简单查询 测试代码: package com.pipi. ...
- Spring Data JPA 之 @Query 语法详解及其应用
5 Spring Data JPA 之 @Query 语法详解及其应用 5.1 快速体验 @Query 的方法 沿⽤我们之前的例⼦,新增⼀个 @Query 的⽅法: // 通过 query 注解根据 ...
- one-many和many-one的关系中的inverse的详解
在one-many和many-one的关系中的inverse的详解. 1.现在假设有两个类Customer与Order,一个Customer可以有多个Order 2. 如果在Customer.hbm. ...
- mysql单表查询实例_MySQL简单查询详解-单表查询
MySQL简单查询详解-单表查询 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查询的执行路径 一条SQL查询语句的执行过程大致如下图所示: 1>.客户端和服务端通过my ...
- Django 模型层(models) 复杂查询详解
Django 模型层(models) 复杂查询详解 一般Django orm 和原生sql混合使用 1.测试文件 只单独测试django中的某一个py文件 不一定是tests.py 1.配置 在任意一 ...
- Ehcache 中ehcache.xml 配置详解和示例
EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider. Ehcache是一种广泛使用的开源Java分布式缓存.主要面向通用缓存 ...
- Android中的四大组件详解
Android中的四大组件详解 我们都知道Android系统应用层框架中,为开发者提供了四大组件来便于应用的开发,它们是Activity.Service.BroadcastReceiver.Conte ...
最新文章
- 手把手教你使用 YOLOV5 训练目标检测模型
- 软件:向工业互联网产业成功转型的关键
- GMIC来了 HTC VIVE细化VR梦
- 十恶不赦到底是哪十恶?
- 黑莓 7290 快捷键
- Fast Non-Bayesian Poisson Factorization for Implicit-Feedback Recommendations
- Ubuntu 12.04无法识别华为U8500
- 当电脑硬盘坏道出现时,如何屏蔽
- vue 如何使用md5密码加密
- java抽奖系统的设计参考文献,抽奖系统的设计与实现论文范文论文
- 项目启动大会的注意事项
- 找准山西智慧城市建设的着力点
- 黄蓝专场之 | 小蓝单车生死故事
- 中国石油大学华东2013-2014-1c语言a卷_答案,中国石油大学(华东)2012—2013学年第二学期期中A卷试卷答案...
- jq+css3树叶飘散特效
- SLF4J(六) - MDC/MDCAdapter是什么?
- JAVA 删除json中反斜杠_如何去除spring的ModelMap的返回类型的JSON序列化字符串中带有反斜杠符号...
- Spring 注解 属性赋值与自动注入装配
- 容器化技术【Kubernetes】
- 国内免费(开源)CMS系统【大全】