如何在Hibernate中进行SELECT查询包括子查询COUNT(*)
假设我们有一个类别 – 项目 一对多关系。 我想这样做
SELECT c.*, (SELECT COUNT(*) FROM items i WHERE i.catId=c.id) AS itemCount FROM category c
让我们说我们有一个Hibernate POJO“类别”。
我的第一个问题是我真的无法弄清楚从那个查询我得到一个List 对象吗? 我怎样才能访问“itemCount”? 因为没有Category.getItemCount()
其次,我如何编写Criteria查询?
谢谢
似乎这是我正在寻找的答案(进入POJO):
@Formula(value="(SELECT COUNT(*) FROM Items i WHERE i.id = id)") @Basic(fetch=FetchType.EAGER) public Integer getItemCount() { return this.taskCount; }
根据您的具体情况和创建视图的能力。 我只想从您的查询中创建一个视图:
CREATE VIEW CategoryItemsView AS SELECT c.*, (SELECT COUNT(*) FROM items i WHERE i.catId=c.id) AS itemCount FROM category c
之后你可以查询你喜欢的…
SELECT * FROM CategoryItemsView WHERE ItemCount = 5
此外,您可以使用GROUP BY来实现类似的结果,但这取决于您的列和表的架构。
所以,像这样:
SELECT c.COLUMN1, c.COLUMN2, COUNT(*) AS ItemCount FROM category c inner join items i on i.catID = c.Id GROUP BY c.COLUMN1, c.COLUMN2 HAVING COUNT(*) = 2
关于查询
受到@ a_horse评论的启发,我为了类似的目的,用真实的生命表进行了快速测试。
- 80个类别
- 6862项
- 最佳索引(在
items.catID
。还有更多,但在这里items.catID
。)
三名候选人。 结果是相同的。 查询计划和性能各不相同。
1)每个类别的子选择(Seregwethrin的原始版本)
总运行时间:20.351 ms
SELECT c.* ,(SELECT COUNT(*) FROM items i WHERE i.catid = c.id) AS item_ct FROM category c
2)LEFT JOIN,然后是GROUP
总运行时间:36.320 ms
SELECT c.* ,count(*) AS item_ct FROM category c LEFT JOIN items i ON i.catid = c.id GROUP BY c.catid; -- prim. key of category
3)GROUP,然后LEFT JOIN
总运行时间: 18.588 ms
SELECT c.* ,item_ct FROM category c LEFT JOIN ( SELECT catid ,count(*) AS item_ct FROM items GROUP BY catid ) i ON i.catid = c.id
所以,我的第一个建议没有任何好处。 正如预期的那样(经过一番思考),版本3)表现最佳。 这也是有道理的:如果先计算,然后再加入,则需要更少的连接操作。
对于较大的表,性能的差异将变得更加明显,尤其是对于更多类别。
为了2)工作,你需要PostgreSQL 9.1和category.id
需要是主键。
对于旧版本,您必须列出GROUP BY子句中的所有非聚合列。
我一般切换到LEFT JOIN
,因为原始查询包括没有关联项的类别。
items.catID
上的索引仅用于1)多个子查询可以获利的情况。 在其他查询中,顺序扫描更快:无论如何都必须读取所有两个表。
- 如何让Hibernate基于DDL / SQL脚本创建表?
- 非托管线程Spring Quartz Websphere Hibernate
- 在Spring的Session Expiry之前执行自定义事件
- Spring-Hibernate在webapp中使用,什么是Thread安全会话管理的策略
- 在hibernate条件查询中选择“group by”的“all columns”
- Spring 3.1 + Hibernate 4.1 Propagation.Supports问题
- 使用OpenEntityManagerInViewFilter进行延迟初始化?
- 调用getNextException以查看原因:如何使Hibernate / JPA显示数据库服务器消息以查找exception
- 在子类的Hibernate中为每个表指定不同的序列