HQL与Criteria
之前一直都在用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,用习惯了