最近在做一次查询时,需要对查询的结果进行二次过滤,即分组之后再过滤,这种情况下,需要使用having。如以下的例子,我需要查询一个字段和另一个字段的和,并对记录进行分组,但结果集中并不需要总记录数为0的结果。sql语句如下所示:
select a, sum(b) as bsum from t where clause1=? group by a having and sum(b) > 0
这种查询语句,使用hql能够很好地写出来,并且能够很好的运行。但如果条件数不定时,使用hql就需要动态的拼接hql,并且需要根据参数来设置参数。如下所示:
if(StringUtils.hasText("clause1")) hql += "clause1 = :clause1"; //.....其它判断和处理 if(StringUtils.hasText("clause1")) query.setString("clause1", clause1);
在这种情况下,许多的if判断,无论是在编码还是在逻辑处理上都让人麻烦。对于不定的参数查询,qbc是最合适的(当然还有qbe)。但是对于qbc,处理having的这种情况即是不能处理的。
不管使用任何处理情况,都不能从criteria中构建出这个having子句。
经过google之后,网上有一个hibernate的bug报告HHH-1043,http://opensource.atlassian.com/projects/hibernate/browse/HHH-1043 。这个链接中,论述了在hibernate中的问题,并且提供一些解决方案,但这些解决方案都不能很容易的理解和解决问题。
最根本的问题在于,qbc中的criteria,在hibernate内部设计和编码时,都是作为where条件中的一部分来实现的.主要的代码在类CriteriaQueryTranslator的方法getWhereCondition中,在这个方法中,迭代所有的criteria,并作为where条件使用。作为用在group集合中的having子句,并不属于where条件中任何一句。如果强行在criteria中使用having(比如使用Restrictions.sqlRestriction),最终的结果就是将having最终加到了where中条件的一部分。不过,这样生成的sql,即是错的,不会得到任何结果。
直到最新的hibernate 3.6版本,此问题仍然未解决。对于需要处理聚集函数的条件问题,现阶段,除了hql(当然sql也算)。hibernate还没有其它的方法。先就这样吧。
转载请标明出处:i flym
本文地址:https://www.iflym.com/index.php/code/hibernate-qbc-not-support-having.html