首页 > 代码库 > Hibernate的检索及五种数据检索方式

Hibernate的检索及五种数据检索方式

  • 检索数据时的 2 个问题

  • 1). 不浪费内存:当 Hibernate 从数据库中加载 Customer 对象时,

  • 如果同时加载所有关联的 Order 对象, 而程序实际上仅仅需要访问 Customer 对象, 

  • 那么这些关联的 Order 对象就白

  • 白浪费了许多内存.

  • 2). 更高的查询效率:发送尽可能少的 SQL 语句


    类级别的检索策略


    2. 类级别的检索策略:(主要掌握 load 方法和 get 方法的区别!)


    1). 类级别可选的检索策略包括立即检索和延迟检索, 默认为延迟检索

    ①. 立即检索: 立即加载检索方法指定的对象

    ②. 延迟检索: 延迟加载检索方法指定的对象。在使用具体的属性时,再进行加载。使用对象前返回的是一个代理对象


    2). 类级别的检索策略可以通过 <class> 元素的 lazy 属性进行设置

        <class name="Customer" table="CUSTOMERS" lazy="false">

    3). 如果程序加载一个持久化对象的目的是仅仅为了获得它的引用, 可以采用延迟检索。注意出现懒加载异常!

org.hibernate.LazyInitializationException: could not initialize proxy - no Session

    4). 无论 <class> 元素的 lazy 属性是 true 还是 false, Session 的 get() 方法及 Query 的 list() 方法在类级别总是使用立即检索策略。即:只适用于 load 方法。




  • Hibernate检索数据的五种方式:


1.导航对象图检索方式。(根据已经加载的对象,导航到其他对象。)

2.OID检索方式。(按照对象的OID来检索对象。)

3.HQL检索方式。(使用面向对象的HQL查询语言。)

4.QBC检索方式。(使用QBC(Qurey By Criteria) API来检索对象。)

5.本地SQL检索方式。(使用本地数据库的SQL查询语句。)


1、导航对象图检索方式

利用类与类之间的关系来检索对象。譬如我们要查找一份订单,就可以由订单对象自动导航找到订单所属的客户对象。当然,前提是必须在对象-关系映射文件上配置了它们的多对一的关系

  • Order order = (Order)session.get(Order.class,1);
    Customer customer = order.getCustomer();

2、OID检索方式

主要指用Session的get()和load()方法加载某条记录对应的对象。

Customer customer = (Customer)session.get(Customer.class,1);
Customer customer = (Customer)session.load(Customer.class,1);




3、HQL检索方式

HQL(Hibernate Query Language)是面向对象的查询语言,它和SQL查询语言有些相似。在Hibernate提供的各种检索方式中,HQL是使用最广的一种检索方式。它具有以下功能:

    使用 HQL(Hibernate Query Language)查询记录时,不经过 Session 缓存!直接查询数据库,且要求查询的结果是最新的!所以,在进行 HQL 查询之前需要先清理缓存。

  • 在查询语句中设定各种查询条件。

  • 支持投影查询,即仅检索出对象的部分属性。

  • 支持分页查询。

  • 支持分组查询,允许使用group by和having关键字。

  • 提供内置聚集函数,如sum()、min()和max()。

  • 能够调用用户定义的SQL函数。

  • 支持子查询,即嵌套查询。

  • 支持动态绑定参数。

Session类的Qurey接口支持HQL检索方式,它提供了以上列出的各种查询功能。

注:Qurey接口支持方法链编程风格,它的set方法都返回自身实例,而不是返回void类型。方法链编程风格能使程序代码更加简洁。

示例代码:

     //1). 编写一个 HQL 语句
        String hql = "FROM Customer c WHERE c.customerId = ?";
    // 2). 利用 session.createQuery(hql) 创建 Query 对象
        Query query = session.createQuery(hql);
    // 3). 设置展位符的值. 占位符的下标从 0 开始.
        // 动态绑定参数
        query.setInteger(0, 1);
    // 4). 进行查询
        Customer customer = (Customer) query.uniqueResult();

注意:Qurey 接口支持方法链编程风格, 它的 setXxx() 方法返回自身实例。所以可以提供更加简洁的使用方式。

 // 方法链编程风格
        Order order = (Order) session
        .createQuery("FROM Order o WHERE o.orderId = ?")
        .setInteger(0, 2)
        .uniqueResult();
        System.out.println(order);


 分页查询:

1). setFirstResult(int firstResult): 设定从哪一个对象开始检索, 参数 firstResult 表示这个对象在查询结果中的索引位置, 索引位置的起始值为 0. 

默认情况下, Query 从查询结果中的第一个对象开始检索

2). setMaxResults(int maxResults): 设定一次最多检索出的对象的数目. 在默认情况下, Query 和 Criteria 接口检索出查询结果中所有的对象





4、QBC(Qurey ByCriteria)检索方式

采用HQL检索方式时,在应用程序中需要定义基于字符串形式的HQL查询语句。QBC API提供了检索对象的另一种方式,它主要由Criteria接口Criterion接口和Expression类组成,它支持在运行时动态生成查询语句

示例代码:

Criteria criteria =session.createCriteria(Customer.class);
Criterion criterion1 = Expression.like("namr","T%");
Criterion criterion2 = Expression.eq("age", newInteger(21));
criteria = criteria.add(criterion1);
criteria = criteria.add(criterion2);
// 执行检索 Listresult = criteria.list();
// 方法链编程风格 
Listresult1 =session.createCriteria(Customer.class).
add(Expression.like("namr""T%")).add(Expression.
eq("age", new Integer(21))).list();

Hibernate还提供了QBE(Qurey By Example)检索方式,它是QBC的子功能。QBE允许先创建一个随想模板,然后检索出和这个样板相同的对象。

示例代码:

Customer exampleCustomer=new Customer();

exampleCustomer.setAge(21);

List result1 = session.createCriteria(Customer.class).add(Example.create(exampleCustomer)).list();

QBE的功能不是特别强大,仅在某些场合下有用。一个典型的使用场合就是在查询窗口中让用户输入一系列的查询条件,然后返回匹配的对象。QBE方式目前只能支持对象属性字段的等于查询和字符串的模糊匹配,不能支持区间,或者,大于等操作。在这些情况下,还是采用HQL检索方式或QBC检索方式。


5、本地SQL检索方式

采用HQLQBC检索方式时,Hibernate生成标准的SQL查询语句,用于所有的数据库平台,因此这两种检索方式都是跨平台的。有的应用程序可能需要根据底层数据库的SQL方言,来生成一些特殊的查询语句。在这种情况下,可以利用Hibernate提供的SQL检索方式

示例代码:

  • Query query = session.createSQLQuery("select {c.*} from
  • CUSTOMER as c where c.NAME  like :customerName
  • andc.AGE=:customerAge");
    // 动态绑定参数 query.setString("customerName", "Test");
  • query.setInteger("customerAge", 21);
    // 执行检索 List result = query.list();



  • End

  • ref-http://www.2cto.com/kf/201402/276783.html