Hibernate检索方式

本文记录Java学习过程中遇到的Hibernate检索方式~

Hibernate的检索方式主要有5种,分别是导航对象图检索方式、OID检索方式、HQL检索方式、QBC检索方式和SQL检索方式。下面对这5种检索方式的使用进行讲解:

对象图导航检索

对象图导航检索方式是根据已经加载的对象,导航到他的关联对象。它利用类与类之间的关系来检索对象。比如,要查找一个联系人对应的客户,就可以由联系人对象自动导航找到联系人所属的客户对象。当然,前提是必须在对象关系映射文件上配置了多对一的关系。

示例代码:

LinkMan linkMan = (LinkMan)session.get(LinkMan.class, 1L);
Customer customer = linkMan.getCustomer();

OID检索方式

OID检索方式主要是用Session的get()和load()方法加载某条记录对应的对象。

示例代码:

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

HQL检索

HQL(Hibernate Query Language)是面向对象的查询语言,它和SQL查询语言有些相似,但它使用的是类、对象和属性的概念,而没有表和字段的概念。在Hibernate提供的各种检索方式中,HQL是官方推荐的查询语言,也是使用最广泛的一种检索方式。

它具有如下功能:

  • 在查询语句中设定各种查询条件;
  • 支持投影查询,即仅检索出对象的部分属性;
  • 支持分页查询;
  • 支持分组查询,允许使用group by和having关键字;
  • 提供内置聚合函数,如sum()、min()和max()等;
  • 能够调用用户定义的SQL函数;
  • 支持自查询,即嵌套查询;
  • 支持动态绑定参数。

Hibernate提供的Query接口是专门的HQL查询接口,它能够执行各种复杂的HQL查询语句。

完整的HQL语句的结构如下:

select ... from ... where ... group by ... having ... ordery by ... asc/desc

可见HQL查询非常类似于标准SQL查询。通常情况下,当检索数据表中的所有记录时,查询语句中可以省略select关键字,示例如下:

from User

如果执行该查询语句,则会返回应用程序中的所有Customer对象,需要注意的是Customer是类名,而不是表名,类名需要区分大小写,而关键字from不区分大小写。

示例代码:

// 基本查询
Query query =  session createQuery("from Customer");
List<Customer> list = query.list();

// 别名
Query query =  session createQuery("select c from Customer c");
List<Customer> list = query.list();

for (Customer c : list) {
	System.out.println(c);
}

// 排序查询
Query query =  session createQuery("from Customer order by cust_id desc");
List<Customer> list = query.list();

for (Customer c : list) {
	System.out.println(c);
}

// 条件查询-?
Query query =  session createQuery("from Customer where cust_name = ?");
query.setString(0, "oliver");
query.setParameter(0, "oliver");
List<Customer> list = query.list();

// 条件查询-变量
Query query =  session createQuery("from Customer where cust_name = :name");
query.setString("name", "oliver");
query.setParameter("name", "oliver");
List<Customer> list = query.list();

// 分页查询
Query query =  session createQuery("from Customer order by cust_id desc");
query.setFirstResult(5);
query.setMaxResult(5);
List<Customer> list = query.list();

// 统计查询
Query query =  session createQuery("select count(*) from Customer");
Long num = (Long)query.uniqueResult();

// 投影查询-单列
Query query =  session createQuery("select cust_name from Customer");
List<String> list = query.list();

// 投影查询-多列
Query query =  session createQuery("select cust_id,cust_name from Customer");
List<Object[]> list = query.list();

// 构造方式的投影查询
Query query =  session createQuery("select new Customer(cust_id,cust_name} from Customer");
List<Customer> list = query.list();

QBC检索

QBC(Query By Criteria)是Hibernate提供的另一种检索对象的方式,它主要由Criteria接口、Criterion接口和Expression类组成。Criteria接口是Hibernate API中的一个查询接口,它需要由session进行创建。Criterion是Criteria的查询条件,在Criteria中提供了add(Criterion criterion)方法来添加查询条件。

QBC的检索是使用Restrictions对象编写查询条件的,在Restrictions类中提供了大量的静态方法来创建查询条件。常用的方法如下:

  • eq:等于;
  • allEq:使用Map,使用key/value进行多个等于的比较;
  • gt:大于;
  • ge:大于等于;
  • lt:小于;
  • le:小于等于;
  • between:对应SQL的between子句;
  • like:对应SQL的like子句;
  • in:对应SQL的in子句;
  • and:and关系;
  • or:or关系;
  • sqlRestriction:SQL限定查询。

示例代码:

// 简单查询
Criteria criteria = session.createCriteria(Customer.class);
List<Customer> list = criteria.list();

// 条件查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.eq("csut_name", "oliver"));
List<Customer> list = criteria.list();

// 分页查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.setFirstResult(5);
criteria.setMaxResults(5);
List<Customer> list = criteria.list();

// 排序查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.addOrder(Order.desc("cust_id"));
List<Customer> list = criteria.list();

// 统计查询
Criteria criteria = session.createCriteria(Customer.class);
criteria.setProjection(Projections.rowCount());
Long count = (Long) criteria.uniqueResult();

离线条件检索:

DetachedCriteria翻译为离线条件查询,因为它是可以脱离Session来使用的一种条件查询对象。Criteria对象必须由Session对象来创建,也就是说必须先有Session才可以生成Criteria对象,而DetachedCriteria对象可以在其他层对条件进行封装。

这个对象也是比较有用的,尤其是在SSH整合以后,这个对象经常会使用。它的主要优点是做一些特别复杂的条件查询的时候,往往会在WEB层向业务层传递很多的参数,业务层又会将这些参数传递给DAO层。最后,在DAO层中拼接SQL完成查询。有了离线条件查询对象后,这些工作都可以不用关心了,我们可以在WEB层将数据封装好,传递到业务层,再由业务层传递给DAO完成查询。

SQL检索

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

示例代码:

SQLQuery sqlQuery = session.createSQLQuery("select * from Customer");

标签: none