分享知识-快乐自己:Hibernate 中Criteria Query查询详解
1):Hibernate 中Criteria Query查询详解
当查询数据时,人们往往需要设置查询条件。在SQL或HQL语句中,查询条件常常放在where子句中。
此外,Hibernate还支持Criteria查询(Criteria Query),这种查询方式把查询条件封装为一个Criteria对象。
在实际应用中,使用Session的createCriteria()方法构建一个org.hibernate.Criteria实例,然后把具体的查询条件通过Criteria的add()方法加入到Criteria实例中。
这样,程序员可以不使用SQL甚至HQL的情况下进行数据查询,如例程9-1所示。
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());
Restrictions.eq()方法表示equal,即等于的情况。
Restrictions类提供了查询限制机制。
它提供了许多方法,以实现查询限制。
这些方法及其他一些criteria常用查询限制方法列于表9-1中:
|
方 法 |
说 明 |
|
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查询详解的更多相关文章
- Hibernate 中Criteria Query查询详解【转】
当查询数据时,人们往往需要设置查询条件.在SQL或HQL语句中,查询条件常常放在where子句中.此外,Hibernate还支持Criteria查询(Criteria Query),这种查询方式把查询 ...
- Hibernate框架笔记04HQL_QBC查询详解_抓取策略优化机制
目录 1. Hibernate的查询方式 1.1 方式一:OID查询 1.2 方式二:对象导航查询 1.3 方式三:HQL方式 1.4 方式四:QBC查询 1.5 方式五:SQL查询 2. 环境搭建 ...
- Hibernate中的事务处理流程详解
一.Hibernate操作的基本流程 使用 Hibernate 进行数据持久化操作,通常有如下步骤: 1.编写持久化类: POJO + 映射文件 2.获取 Configuration 对象 3.获取 ...
- Oracle中的层次查询详解
1 语法格式 select [level], column, expr... from table [where condition] start with condition connect by ...
- Hibernate中的一对一关系详解(1)
A:先讲讲一对一的关系(欲知其他关系,请看下篇) a:主键关联的一对一关系 一对一关系一般用主键关联,也就是说用主键值来维护两者的关系,一个表的主键存放另一个表的主键值.例如在员工与帐号中,我们取员工 ...
- Atitit.Hibernate中Criteria 使用总结and 关联查询 and 按照子对象查询 o9o
Atitit.Hibernate中Criteria 使用总结and 关联查询 and 按照子对象查询 o9o 1. Criteria,,Criterion ,, 1 <2. 主要的对象黑头配置磊 ...
- Hibernate中Criteria的完整用法2
Criteria的完整用法 QBE (Query By Example) Criteria cri = session.createCriteria(Student.class); cri.add(E ...
- Hibernate中关于HQL查询返回List<Object>数据的结果集问题
---恢复内容开始--- 开发中遇到的一个小问题,使用Hibernate中的HQL查询时,使用query.list()查询出来的是一个List<Object>结果集 原来代码: publi ...
- Hibernate中的条件查询完成类
Hibernate中的条件查询有以下三个类完成: 1.Criteria:代表一次查询 2.Criterion:代表一个查询条件 3.Restrictions:产生查询条件的工具类
随机推荐
- Android Canvas之Path操作
接上篇,Android自己定义View工具:Paint&Canvas(二) 上一篇中介绍的Canvas绘制图形仅仅能画一些常规图形(圆.椭圆.矩形等),假设想绘制更复杂的图形.Path神器来了 ...
- remove-duplicates-from-sorted-array-ii——去除重复
Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For exampl ...
- 在Ubuntu 14.04 64bit中永久添加DNS的方法
DNS信息是由/etc/resolv.conf提供的,它是每次开机时,由/sbin/resolvconf生成的/etc/resolv.conf是/run/resolvconf/resolv.conf的 ...
- UIView属性的动画
//标记着动画块的开始,第一个参数表示动画的名字,起到标识作用 [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDurat ...
- svn自动部署
版本库目录hooks下创建post-commit.bat TortoiseProc.exe /command:update /path:"E:\web_server\sial\" ...
- Xenomai PC开发环境
这两天总在纠结编译一个PC机上的Xenomai开发环境,选择编译器.kernel版本和IPIP版本,但是今天忽然想到,上位机只是个开发环境,只要能编译.能运行就可以了,实时性根本不是关注的东西.而Xe ...
- 常用string函数分析
string函数分析string函数包含在string.c文件中,经常被C文件使用.1. strcpy函数原型: char* strcpy(char* str1,char* str2);函数功能: 把 ...
- 32.10 使用模板更改控件的UI
32.10 使用模板更改控件的UI 样式是改变WPF控件基本外形的非常好(且非常简单)的方式,它通过为窗口部件的特性设置建立一组默认的值,从而改变WPF控件的基本外形.但是,即使样式允许我们改变各种 ...
- C#下的摄像机标定
前言:计算机视觉的基本任务之一是从摄像机获取的图像信息出发计算三维空间中物体的几何信息,并由此重建和识别物体,而空间物体表面某点的三维几何位置与其在图像中对应点之间的相互关系是由摄像机成像的几何模型决 ...
- Unity3D研究院之Inspector视图中的get/set使用
get set 使用起来很方便,但是编辑时在Inspector视图中问题就来了,因为get/set的属性即使是public了,但是在Inspector视图中依然不显示..谷歌一下估计就是下面这样的答案 ...