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后才有的)。  
 

标签:Hibernate,查询
0
投稿

猜你喜欢

  • Android基准配置文件Baseline Profile方案提升启动速度

    2022-08-12 18:54:42
  • Java中计算时间差的方法

    2023-11-15 10:35:44
  • Android Studio 3.0中mipmap-anydpi-v26是什么东东

    2023-10-11 01:17:44
  • Android编程开发之EditText中inputType属性小结

    2022-04-13 10:03:11
  • C#抽象类与抽象方法详解

    2022-05-20 18:08:03
  • Java实现SSL双向认证的方法

    2023-09-22 10:34:35
  • c# 判断是否为空然后赋值的4种实现方法

    2021-06-06 22:01:12
  • 超全MyBatis动态代理详解(绝对干货)

    2023-11-14 02:28:19
  • DevExpress实现GridView当无数据行时提示消息

    2023-08-23 04:13:33
  • Java8新特性之接口中的默认方法和静态方法详解

    2022-05-10 15:16:19
  • Kotlin使用协程实现高效并发程序流程详解

    2021-12-27 20:47:21
  • 详解AndroidStudio JNI +Gradle3.0以上JNI爬坑之旅

    2021-09-01 05:45:04
  • 解决spring security中遇到的问题

    2023-05-08 11:26:46
  • Java并发编程示例(七):守护线程的创建和运行

    2023-11-25 11:39:32
  • 详解Java的MyBatis框架和Spring框架的整合运用

    2022-09-19 19:22:20
  • Java获取彩色图像中的主色彩的实例代码

    2021-10-16 01:09:39
  • Android开发中使用Intent打开第三方应用及验证可用性的方法详解

    2021-08-12 19:28:47
  • Java数据结构之ArrayList从顺序表到实现

    2022-06-14 00:53:25
  • Spingboot JPA CriteriaBuilder 如何获取指定字段

    2022-07-20 15:40:22
  • Java 数据结构与算法系列精讲之队列

    2023-09-26 21:10:31
  • asp之家 软件编程 m.aspxhome.com