Java的Hibernate框架中Criteria查询使用的实例讲解
作者:cxshun 发布时间:2023-08-22 23:25:47
我们讲一下Criteria查询,这个对于不是太熟悉SQL语句的我们这些程序员来说是很容易上手的。
废话不多说,看一下例子:
实体类如下:
public class User implements Serializable{
private static final long serialVersionUID = 1L;
public Long id;
private String name;
private int age;
//省略Get/Set方法
}
映射文件我们就不写了,很简单的一个实体,如果不懂的童鞋请参照我在hibernate分类中的其他文章。
接下来我们看如何使用Criteria来进行查询:
public static void main(String[] args) {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.eq("name","shun"));
List list = criteria.list();
Iterator iter = list.iterator();
while(iter.hasNext()) {
User user = (User)iter.next();
System.out.println(user.getName()+":"+user.getAge());
}
session.close();
}
看到代码,很简单的一串。
前面都很熟悉啦,我们看到构造session之后的代码:
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.eq("name","shun"));
这两句代码是重点,我们来分析一下,究竟是什么意思?
第一句我们通过session得到Criteria实现类的一个对象,接着第二句我们通过add方法添加一个条件,eq表示相等。在Hibernate3以前是通过Expression.eq来实现,3之后由于Criteria被抛弃,我们改用Restrictions类来实现,它和Expression一样的用法。我们看看API发现Expression继承于Restrictions。
回到我们上面的两句,我们做完这些工作后,实际上hibernate帮我们构造了类似
select * from user where name='shun'
这样的语句。(这里我们映射文件中User类对应的表是user表,而name属性对应的是name字段)
Restrictions还有许多帮助我们构造SQL语句的方法,大家查一下API很容易就可以理解了。
我们重新看一下上面的代码,如果我们关闭了session,但是我们想继续使用这个criteria,行吗?我们来看一下。
在上面的代码之后,我们重新遍历,加上:
List list2 = criteria.list();
Iterator iter2 = list.iterator();
while(iter.hasNext()) {
User user = (User)iter.next();
System.out.println(user.getName()+":"+user.getAge());
}
为了区分跟上一个list和iter的区别,我们这里用另外一个。
运行它,我们得到的是一个异常:
org.hibernate.SessionException: Session is closed!
报这个异常表示session已经关闭,很多情况下我们在关闭了session再进行saveOrUpdate,save等跟持久化相关的操作都会报类似的异常。
Hibernate3考虑到了我们这个需求,它实现了一个DetachedCriteria,这个可以独立于Session而存在。
我们来看一下例子:(实体还是上面的)
public static void main(String[] args) {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
DetachedCriteria decriteria = DetachedCriteria.forClass(User.class);
decriteria.add(Restrictions.eq("name","shun"));
List list = decriteria.getExecutableCriteria(session).list();
Iterator iter = list.iterator();
while(iter.hasNext()) {
User user = (User)iter.next();
System.out.println(user.getName()+":"+user.getAge());
}
session.close();
Session session2 = sessionFactory.openSession();
List list2 = decriteria.getExecutableCriteria(session2).list();
Iterator iter2 = list2.iterator();
while(iter2.hasNext()) {
User user = (User)iter2.next();
System.out.println(user.getName()+":"+user.getAge());
}
}
我们看到在session关闭之后,我们在另外一个连接中还是可以继续用DetachedCriteria。我们需要通过getExecutableCriteria(Session session)把当前的DetachedCriteria跟某一个Session进行关联。
接下来我们再来看一下Subqueries类与DetachedCriteria的结合使用:
public static void main(String[] args) {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
DetachedCriteria decriteria = DetachedCriteria.forClass(User.class);
decriteria.setProjection(Projections.avg("age"));
Criteria criteria = session.createCriteria(User.class);
criteria.add(Subqueries.propertyGt("age",decriteria));
List list = criteria.list();
Iterator iter = list.iterator();
while(iter.hasNext()) {
User user = (User)iter.next();
System.out.println(user.getName()+":"+user.getAge());
}
session.close();
}
估计大家有疑问的应该是第一句代码:
decriteria.setProjection(Projections.avg("age"));
这句代码是指通过decriteria得到age的平均值。然后在下面取得大于平均值的age的对象。
Projections包含了许多实现SQL方法的封装方法,大家可以看一下API。
下面我们来了解一下它的稍微高级点的用法。
直接看代码吧:
criteria.setFirstResult(10);
criteria.setMaxResults(20);
这里我们设置了开始的记录是第10条,然后从第10条开始查出20条记录,根据这个做法,我们就可以实现基本的分页功能了。
当然,我们在很多情况下都需要排序,criteria也是支持的:
criteria.addOrder(Order.desc("age"));
这里,我们直接用addOrder方法即可,里面通过Order.desc得到一个Order对象,它需要一个属性参数。实际上当我们调用addOrder时,hibernate会帮我们生成order by age,这样的语句。
当我们需要进行分组时,这个怎么做呢?这个就需要用到我们上次有涉及到的Projections这个类的groupProperty方法,
criteria.setProjection(Projections.groupProperty("age"));
这里我们就根据age属性来进行分组,实际上也就是通过age对应的字段age进行分组,hibernate会自动帮我们转换成group by age这样的语句。
Projections中有许多实用的方法(注意,此为是hibernate 3后才有的)。
猜你喜欢
- 实现原理: 长连接的维持,是要客户端程序,定时向服务端程序,发送一个
- 一、获取android工程里面的各种资源的id; 1.1 string型 比如下面: << string name=”OK”&g
- 光流的概念是由一个叫Gibson的哥们在1950年提出来的。它描述是空间运动物体在观察成像平面上的像素运动的瞬时速度,利用图像序列中像素在时
- 本文实例为大家分享了flutter实现倒计时加载页面的具体代码,供大家参考,具体内容如下效果图实现步骤1、pubspec.yaml中添加依赖
- Android植物大战僵尸小游戏全部内容如下:相关下载:Android植物大战僵尸小游戏具体代码如下所示:package com.examp
- 起源flutter作为一个跨平台的框架,在绘制上体现出了它跨平台的良好性能.那么,它是如何从runApp()后 绘制上屏的呢?本文将与你一起
- 1、什么是servlet异步请求Servlet 3.0 之前,一个普通 Servlet 的主要工作流程大致如下:(1)、Servlet 接收
- 准备:wildfly/tomcat或者其他服务器你的数据库的Driver,(此处用的mysql-connecter-java-5.1.39-
- 前言多数据源的事务处理是个老生常谈的话题,跨两个数据源的事务管理也算是分布式事务的范畴,在同一个JVM里处理多数据源的事务,比较经典的处理方
- 路由做Android/iOS原生开发的时候,要打开一个新的页面,你得知道你的目标页面对象,然后初始化一个Intent或者ViewContro
- 我就废话不多说了,大家还是直接看代码吧~<?xml version="1.0" encoding="UT
- Android基础教程数据存储之文件存储将数据存储到文件中并读取数据1、新建FilePersistenceTest项目,并修改activit
- 今天讲解一下Fragment的控制,主要是切换View和页面替换等操作。还有就是如何获取Fragment的管理对象,以及与Activity的
- 近日于LeetCode看题遇1114 按序打印,获悉一解法使用了Semaphore,顺势研究,记心得于此。此解视Semaphore为锁,以保
- 前提说明之前公司有一个项目是由androidstudio接入高德地图实现导航,定位等功能,然后还有一部分登陆页面和其他逻辑都放在Unity方
- SpringCloud 整合ribbon的时候出现了这个问题java.lang.IllegalStateException: No inst
- 具体代码如下所示:***web.xml***<?xml version="1.0" encoding="
- 模拟登陆的原理很简单,就是发送一个Http 请求服务器获得响应,然后客户端获取到cookie即可实现模拟登陆,比如一些抢票软件的原理无非也是
- 有时候,我们需要制作一个Word模板文档,然后发给用户填写,但我们希望用户只能在指定位置填写内容,其他内容不允许编辑和修改。这时候我们就可以
- 其他的不多说了!我们来看看效果吧 一、实现方式一:直接引入compile方式A