一、Hibernate 的查询方式
1.1 SQL
全称 Structured Query Language。
static List sql() {
Session s = HibernateUtil.getSession();
Query q = s.createSQLQuery("select * from user").addEntity(User.class);
List<User> rs = q.list();
s.close();
return rs;
}
违背了 hibernate 的跨平台优点,不易维护,不面向对象。
1.2 HQL
全称 Hibernate Query Language。
@Override
public SysUser findUserByLoginName(String loginName) {
String hql = "from SysUser as u where u.loginName = ?";
List<SysUser> users = getHibernateTemplate().find(hql, loginName); // loginName 对应 '?' 符号
return users.isEmpty() ? null : users.get(0);
}
1.3 QBC
全称 Query By Criteria。
QBC 查询的基本步骤
这种方式比较面向对象方式,重点是有三个描述条件的对象:
Restrictions
、Order
、Projections
。使用 QBC 查询,一般需要以下三个步骤:- 使用 Session 实例的 createCriteria() 方法创建 Criteria 对象;
- 使用工具类 Restrictions 的方法为 Criteria 对象设置查询条件,Order 工具类的方法设置排序方式,Projections 工具类的方法进行统计和分组;
- 使用 Criteria 对象的 list() 方法进行查询并返回结果。
Restrictions、Order、Projections的常用方法
QBC 的查询示例和基本理解
Criteria c = s.createCriteria(Admin.class); c.add(Restrictions.eq("NAME", "Jack"));
c.add(Restrictions.eq("PASSWORD", "123456"));
List<Admin> list = c.list();// 分页查询前 10 条 Criteria criteria = session.createCriteria(Customer.class);
criteria.addOrder(Order.asc("NAME"));
criteria.setFirstResult(0);
criteria.setMaxResults(10);
List result = criteria.list()org.hibernate.Criteria
实际上是个条件附加的容器,如果想要设定查询条件,则要使用 org.hibernate.criterion.Restrictions 的各种静态方法传回org.hibernate.criterion.Criterion
实例,传回的每个 org.hibernate.criterion.Criteria 实例代表着一个条件,你要使用org.hibernate.Criteria 的 add() 方法加入这些条件实例。示例:
// 查找 age 等于(eq)20或(or)age为空(isNull)的User Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.or( Restrictions.eq("age", new Integer(20)), Restrictions.isNull("age") ));
List users = criteria.list();
// 实际上产生的对应的 sql:
Hibernate:
select
this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_
from
T_USER this_
where
(this_.age=? or this_.age is null)复合查询
复合查询就是在原有的查询基础上再进行查询。
// 查询“包含学生姓名为 Bob”的班级 Criteria criteria = session.createCriteria(Clazz.class);
Criteria criteriaInner = criteria.createCriteria(Student.class);
criteriaInner.add(Restrictions.eq("NAME", "Bob"));
List clazzList = criteria.list();如果是 DetachedCriteria,则是根据关联属性的名称,而非 Class,如:
Member member = MemberHelper.getCurrentLoginMember(); DetachedCriteria criteria = DetachedCriteria.forClass(Picture.class);
DetachedCriteria collectCriteria = criteria.createCriteria("collectRecordList");
collectCriteria.add(Restrictions.eq("member", member));
List<Picture> pictureList = Picture.listByCriteria(criteria, page, Order.desc("updateDate"));Hibernate 中 Criteria 方式的基本使用流程
- Criteria 创建
- 条件添加
- 结果返回
二、DetachedCriteria
2.1 是什么?
父接口 CriteriaSpecification
,其下有子接口 Criteria 和实现类DetachedCriteria,Criteria 和 DetachedCriteria 均可使用Criterion 和 Projection 设置查询条件。可以设置 FetchMode(联合查询抓取的模式),设置排序方式。对于 Criteria 还可以设置 FlushModel(冲刷 Session 的方式)和 LockMode(数据库锁模式)。
2.2 与 Criteria 的区别
Criteria 和 DetachedCriteria 的主要区别在于创建的形式不一样,Criteria是在线的,所以它是由Hibernate Session进行创建的;而 DetachedCriteria 是离线的,创建时无需 Session,它通过两个静态方法 forClass(Class) 或 forEntityName(Name) 进行 DetachedCriteria 的实例创建。
Spring 的框架提供了 getHibernateTemplate ().findByCriteria(detachedCriteria) 方法可以很方便地根据DetachedCriteria 来返回查询结果。
所以它也称为离线条件查询,即建立一个 DetachedCriteria 对象,将查询的条件等指定好,然后在 session.beginTransaction() 后将这个对象传入。通常这个对象可以在表示层建立,然后传入业务层进行查询。
2.3 基本使用
/* 查询 id = 1 且在今天或今天之前出生的 user 的名单 */
DetachedCriteria dc = DetachedCriteria.forClass(User.class);
int id = 1;
dc.add(Restrictions.eq("id", id));
Date age = new Date();
dc.add(Restrictions.le("birthday", age));
Session session = HibernateUtil.getSession();
Criteria c = dc.getExecutableCriteria(session);
List users = c.list();
DetachedCriteria 并没有像 Criteria 一样有 list() 的方法来返回 List,所以需要以此获取一个可执行的 Criteria,达到真正执行查询的目的。
org.hibernate.criterion
Class DetachedCriteria
getExecutableCriteria
public Criteria getExecutableCriteria(Session session)
Get an executable instance of Criteria, to actually run the query.