我们讲一下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后才有的)。
本文向大家介绍实例讲解Java的Spring框架中的AOP实现,包括了实例讲解Java的Spring框架中的AOP实现的使用技巧和注意事项,需要的朋友参考一下 简介 面向切面编程(AOP)提供另外一种角度来思考程序结构,通过这种方式弥补了面向对象编程(OOP)的不足。 除了类(classes)以外,AOP提供了 切面。切面对关注点进行模块化,例如横切多个类型和对象的事务管理。 (这些关注点术语通常
本文向大家介绍写简单的mvc框架实例讲解,包括了写简单的mvc框架实例讲解的使用技巧和注意事项,需要的朋友参考一下 这一章先把支持注解的功能加上,这样就不需要经常地修改配置文件了。 至于视图处理的地方,就还是先用json吧,找时间再写。 项目地址在:https://github.com/hjx601496320/aMvc 。 测试代码在:https://github.com/hjx60149632
问题内容: 我正在将子系统从 NHibernate 移植到 Entity Framework, 并希望看到将以下查询移植到 EF 的最佳方法。 帐户余额类别为: 该表是: 示例数据是(使用数字ID可以更好地理解): 该 AccountBalanceByDate 实体持有某一天的账户余额。如果某天没有交易,则该天将没有 AccountBalanceByDate ,我们应该查看前几天以查看该帐户的余额
本文向大家介绍举例讲解Java的Hibernate框架中的多对一和一对多映射,包括了举例讲解Java的Hibernate框架中的多对一和一对多映射的使用技巧和注意事项,需要的朋友参考一下 多对一(Many-to-One)映射 多对一(many-to-one)关联是最常见的关联关系,其中一个对象可以与多个对象相关联。例如,一个相同的地址对象可以与多个雇员的对象相关联。 定义RDBMS表: 考虑一个情
本文向大家介绍redis在java中的使用(实例讲解),包括了redis在java中的使用(实例讲解)的使用技巧和注意事项,需要的朋友参考一下 1、首先下载jar包放到你的工程中 2、练习 总结:自己可以封装一些工具类方便使用,包括连接池的配置,jedis参数的配置等。 RedisTemplate封装了从JedisPool中取jedis以及返回池中 以上这篇redis在java中的使用(实例讲解)
本文向大家介绍Yii框架where查询用法实例分析,包括了Yii框架where查询用法实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Yii框架where查询用法。分享给大家供大家参考,具体如下: 1.简述 Yii的查询操作找使用where用的很多 总结下常用的哈希格式与操作符格式 2.操作符格式 适用于操作符的 [操作符, 操作数1, 操作数2, ...] and:操作数会被 A