在上一篇的博客《Liferay 6.1开发学习(十九):Liferay ServiceBuilder之自定义查询》之中介绍了一部分简单的Dynamic Query方法,能够知足简单的条件查询,但有些场景这样的查询不能知足咱们的需求,同时使用HQL可能有稍显麻烦,在这里介绍一些Dynamic Query的高级技巧。(Dynamic Query的查询持续更新到此篇博客)html
在Dynamic Query中实现group by的查询其实很是简单,示例代码以下:web
DynamicQuery�0�2query�0�2=�0�2this.dynamicQuery(); �0�2�0�2学习
ProjectionList�0�2list�0�2=�0�2ProjectionFactoryUtil.projectionList(); �0�2�0�2ui
list.add(ProjectionFactoryUtil.rowCount()); �0�2�0�2this
list.add(ProjectionFactoryUtil.groupProperty("bookNo")); �0�2�0�2spa
list.add(ProjectionFactoryUtil.groupProperty("userId")); �0�2�0�2hibernate
query.setProjection(list);�0�2�0�2插件
上面的代码等效于select count(*),bookNo,userId from xxx group by bookNo,userIdorm
若是要再添加相应的过滤条件,则再query上再添加相应的语句,如:htm
query.add(PropertyFactoryUtil.forName("bookName").like("xxx"));
最后调用dynamicQuery(query);便可
DynamicQuery�0�2query�0�2=�0�2this.dynamicQuery(); �0�2�0�2
DynamicQuery�0�2subQuery�0�2=�0�2new�0�2DynamicQueryFactoryUtil().forClass(Author.class); �0�2�0�2
subQuery.setProjection(ProjectionFactoryUtil.property("authorId")); �0�2�0�2
subQuery.add(PropertyFactoryUtil.forName("sex").eq(Boolean.FALSE)); �0�2�0�2
query.add(PropertyFactoryUtil.forName("authorId").in(subQuery)); �0�2�0�2
return�0�2dynamicQuery(query);�0�2�0�2
示例代码如上,等效于如下的SQL:
Select * from books where authorId in(select authorId from author where sex=false)
在Dynamic query中实现or查询有两种方法:
方法一:
Junction junction = RestrictionsFactoryUtil.disjunction();
junction.add(PropertyFactoryUtil.forName("xxxx").like("%"+keyWord+"%"));
junction.add(PropertyFactoryUtil.forName("xxx").like("%"+keyWord+"%"));
junction.add(PropertyFactoryUtil.forName("xxx").like("%"+keyWord+"%"));
query.add(junction);
方法二:
query.add(RestrictionsFactoryUtil.or("条件1",RestrictionsFactoryUtil.or("条件2",RestrictionsFactoryUtil.or("条件3", "条件4"))))
Liferay中的Dynamic Query是封装的Hibernate的Criteria Queries,Dynamic Query的资料虽然相对较少,全面的文档更是难以找到,若是要学习,能够参考hibernate的Criteria Queries的API,点击此处
在Liferay中虽然和Hibernate的使用不彻底同样,可是这上面的API颇有参考价值,应该说是学习Dynamic Query的最好文档。
可能这里有一个疑问,既然hibernate有了Criteria Query,Liferay干吗还要再封装一次?这不是出力又不讨好的事情么?我思考了一下,可能缘由以下:
直接使用Hibernate的原生API,若是咱们要在插件工程中使用,则须要在每个插件工程中引入相应的Hibernate工程,这样对于开发是很是不方便的,如今Liferay封装了相应的接口,咱们在全部的portlet工程里面均可以直接调用,不须要再引入第三方的Jar包,方便二次开发。