Liny_@NotePad

沉迷ACG中

HQL与Criteria

YOYO posted @ 2012年5月18日 16:30 in 【Java EE】 with tags Hibernate , 5848 阅读

之前一直都在用HQL,现在的项目组却更推荐用Criteria,为什么呢……

于是查了下资料,和同学、朋友交流了下,就最浅显的部分做了少少比较,还请指点一二。 > < //

HQL是Hibernate官方推荐的查询方式,涵盖了Criteria的功能,更加全面、灵活,对于熟悉SQL的开发者来说比后者直观许多,维护比较简单,语句执行效率也较高(速度上SQL>HQL>Criteria)。

Criteria则是面向对象的查询方式,毕竟HQL还是字符串拼接,不够OO。Criteria支持动态扩展条件,拼装方便,举例一下,不定条件的查询:

HQL写法大概是这种感觉(实际项目中一般会再做封装,更加简单):

StringBuilder builder = "SELECT emp FROM Employee WHERE 1=1 ";
builder.append(" AND name LIKE :Name ");
if (emp.getSex() != -1) { 
	builder.append(" AND sex = :Sex ");
}
String hql = builder.toString();
Query query = session.createQuery(hql);
query.setString("Name", '%' + emp.getName() + '%');
if (emp.getSex() != -1) { 
	query.setInteger("Sex", emp.getSex());
}
return (List<Employee>) query.list();

而Criteria的写法确实会比较清楚些:

Criteria c = session.createCriteria(Employee.class)
c.add(Restrictions.ilike("name", emp.getName(), MatchMode.ANYWHERE);
if (emp.getSex() != -1) {
	c.add(Restrictions.eq("sex", emp.getSex());
}
return (List<Employee>) c.list();

 这种动态条件查询,用Criteria更加合适,如果要对Hibernate做二次封装,也是用它更好扩展。但如果是不会变动的代码,比起HQL,Criteria反而需要写更多的代码,维护起来也更加困难。

另外一点是个人的问题。HQL在编译的时候只当是普通的字符串,只有在运行的时候才会发现其中可能存在的bug(比如少了间隔的空格或是引号遗漏之类)。如果没有单元测试,粗心大意的话会浪费非常多的时间;而Criteria虽然也无法在编译时对字段名字打错这样的bug进行检查,但至少可以检查到其他如条件、连接这样的语法部分。


附录参考资料:

  • Hibernate Querying 102 : Criteria API》其实只看了最后一段的When the Hibernate Criteria API is not appropriate,在这里提到了命名查询,于是顺便查了相关的资料。
     
  • Hibernate 6种查询》、《Hibernate 命名查询NamedQuery》简单地介绍了Hibernate中的六种查询方式。我个人是喜欢用DetachedCriteria和Example。虽说命名查询在静态查询方面效率最佳,但是配置方法感觉可维护性不是很好。名字不规范的话很难理解其意义,又使得业务代码出现在实体代码中,还是更喜欢直接写本地HQL。
     
  • HQL与Criteria对照》对于常用的查询,HQL与Criteria的写法对比。
伊莉 说:
2013年10月27日 16:38

喜欢hibernate,用习惯了


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter