从数据库中获取对象是Hibernate最有趣的部分之一。Hibernate获取对象的方式有如下几种:
- 根据id获取, 在已知对象id的情况下,这是最方便的.
- 使用Hibernate Query Language (HQL), 面向对象的查询。 Java Persistence query language (JPA QL) 是 Hibernate query language 标准化后的子集.
- 使用Hibernate Criteria , 一种类型安全且面向对象的查询。 包括QBE(Query By Example)查询(后面会有一个例子).
- Native SQL queries, 包含存储过程调用, Hibernate仍然负责将查询结果集封装到对象图上.
Retrieval by identifier:
根据id获取对象将产生一条或多条sql语句(如果出现对象继承或多表查询),id通常是表中的主键。
例如,我们要查询id为100的User对象:
User user = (User) session.load(User.class, new Long(100));
//另一种方式
User user = (User) session.get(User.class, new Long(100));
session.load 和 session.get 有什么区别呢?
根据Hibernate官方文档, 使用load()时,如果在缓存或数据库中找不到指定的对象, 方法将抛出异常并且 load() 不会返回null。get() 方法在找不到对象时将返回null。
load() 返回的是一个代理而不是一个真正的持久化实例。在需要用到实例时,代理才会去加载真正的对象;而get() 返回的不是一个代理。 从 get() 和 load()做出取舍很简单: 如果你确定对象存在, load() 是一个好选择; 如果你不确定具有给定id的对象是否存在, 使用 get() 并且别忘了判断其返回值是否为null。
使用load() 还有进一步的含义: 应用取得了持久化实例的一个有效的引用 (一个代理) 但没有必要从数据库中获取实例的状态。所以load() 方法在没有从缓存或数据库中找到对象时未必会立即抛出异常; 而是在你用到这个代理时,异常才会被抛出。 当然, 根据id获取对象没有下面的几种方式便利。
The Hibernate Query Language (HQL)
多数时候,你仅需要根据限定对象属性来获取对象。例如,下面的查询根据surname获取一个Customer:
Query q = session.createQuery("from Customer as c where c.surname = :surname");
q.setString("surname", "Frank");
List result = q.list();
先创建一个Query对象q, 然后将一个值绑定到命名参数 :fname 上。 调用list方法返回一个Customer的集合.
Hibernate Criteria interface
Hibernate query by criteria (QBC) API 允许你在运行时操作criteria对象。不用直接操纵一个长的查询字符串,你可以动态的绑定结束(查询条件):
Criteria criteria = session.createCriteria(Customer.class);
criteria.add( Restrictions.like("surname", "Frank") );
List result = criteria.list();
Native Queries:
如果你需要用到native queries (特定于某一数据库平台的查询,更利于优化但不建议使用) ,可以像下面这样使用 createNativeQuery 方法:
Query sqlQuery =session.
createNativeQuery("select c.customer_ID, c.customer_NAME, c.customer_SURNAME from Customer c",Customer.class);
下面给出一个Query By Example (QBE)的示例:
public List<Person> find(Person person) {
Session session = getSession();
Example example = Example.create(person)
.enableLike(MatchMode.ANYWHERE)
.excludeZeroes()
.ignoreCase();
List<Person> result = session.createCriteria(Person.class)
.add(example)
.list();
return result;
}