SQL statement conversion to hibernate criteria (having count clause)
我有一个SQL查询,希望将其转换为条件(hibernate3.3.2)以将其用于我的持久性层。
那就是查询:
1 2 3 4 5 6 | select last_name from member where member.end_date > SYSDATE group by member.last_name having count(member.last_name) >1; |
我已经尝试了很多组合,但是没有结果对我有好处……这是我的代码:
1 2 3 4 5 6 7 8 9 10 | Criteria criteria = getSession(false).createCriteria(Member.ENTITY_NAME); criteria.setProjection(Projections.projectionList() .add(Projections.groupProperty("lastName")) .add(Projections.count("lastName").as("cptLastName")) ); criteria.add(Restrictions.ge("endDate", now)) .add(Restrictions.le("startDate", now)) //.add(Restrictions.gt("cptLastName", new Integer(1))) .addOrder(Order.asc("lastName")) ; |
用注释行编写它时,我有一个对象列表,其中包含名称和该名称在数据库中出现的次数。但是当我想将其分解时,出现以下错误:
java.sql.SQLException:ORA-00904:" Y1_":无效的标识符
要开发此代码,我受到以下不同帖子的启发:
-
hibernate条件:按子句分组的投影计数
-
具有某些条件的hibernate计数行
-
我们如何使用Hibernate计算行数?
-
如何在hibernate状态下使用HAVING COUNT(*)
-
hibernate标准API-HAVING子句可解决
我认为我离解决方案不远,但是有人可以帮助我吗?
如果您有任何疑问,请随时问我。
而且,如果您找到了另一个解决方法让我粘贴到此查询中,请不要犹豫地提出它...
您好,如果我是对的,您目前无法在hibernate条件中直接使用Haveing子句计数,请在经过修改的查询下方找到。如果不起作用,请发布整个堆栈跟踪
1 2 3 4 5 6 7 8 | DetachedCriteria innerQuery = DetachedCriteria.forClass(Member.ENTITY_NAME,"inner"); innerQuery.setProjection(Projections.rowCount()); innerQuery.add(Restrictions.eqProperty("lastName","outer.lastName")); Criteria c = s.createCriteria(Member.ENTITY_NAME,"outer"); c.setProjection(Projections.property("lastName")); c.add(Restrictions.gt("endDate", now)) c.add(Subqueries.eq(new Integer(1), innerQuery)); |
实际上,我的回答部分成功了……因为我只展示了我的重要要求的一部分。就像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 | select member.last_name, member.first_name, from member where member.end_date > SYSDATE and member.last_name in (select member.last_name from member where member.end_date > SYSDATE group by member.last_name having count(member.last_name) >1) order by member.last_name; |
它显示数据库中所有具有同名(相同名称)的成员。因此,供您参考,这是我的最终标准:
1 2 3 4 5 6 7 8 9 10 | Calendar now = Calendar.getInstance(); DetachedCriteria innerQuery = DetachedCriteria.forEntityName(Member.ENTITY_NAME,"inner") .setProjection(Projections.rowCount()) .add(Restrictions.eqProperty("lastName","outer.lastName")) .add(Restrictions.ge("endDate", now)); Criteria criteria = getSession(false).createCriteria(Member.ENTITY_NAME,"outer") .setProjection(Projections.property("lastName")) .add(Restrictions.ge("endDate", now)) .add(Subqueries.lt(new Integer(1), innerQuery)); |
为了稍微解释一下,通过投影,我计算了行数,然后将(select的)姓氏与主查询的姓氏进行了比较。
同样,始终需要主要标准的第二行。如果使用子查询(DetachedCriteria),则必须使用Projection。
但是,最后,我使用了HQL查询来运行我的代码,因为该标准使工作更加繁重...
所以,谢谢您的回答...
我根据您的主张修改了代码,这就是我的意思:
1 2 3 4 5 6 7 8 | DetachedCriteria innerQuery = DetachedCriteria.forEntityName(Member.ENTITY_NAME,"inner") .setProjection(Projections.rowCount()) .add(Restrictions.eqProperty("lastName","outer.lastName")); Criteria criteria = getSession(false).createCriteria(Member.ENTITY_NAME,"outer") .setProjection(Projections.property("lastName")) .add(Restrictions.g("endDate", now)) .add(Subqueries.gt(new Integer(1), innerQuery)); |
因此,就像我在上面的评论中说的那样,它可以工作,但是要花很长时间……给我错误的结果(应该给我八条记录)。
我激活了显示hibernate查询的选项(hibernate.show_sql = true)。如果我将其格式化为sql查询格式,这就是说它能够执行:
1 2 3 4 5 6 7 | select this.last_name from member this where this.END_DATE>=SYSDATE and 1 > (select count(*) from member inner where inner.last_name = this.last_name); |
那么,可以使用该查询为我提供想要的结果吗?