Java 如何在Hibernate中进行选择查询包括子查询计数(*)
假设我们有一个类别-项目一对多关系。我想这样做Java 如何在Hibernate中进行选择查询包括子查询计数(*),java,sql,database,hibernate,jakarta-ee,Java,Sql,Database,Hibernate,Jakarta Ee,假设我们有一个类别-项目一对多关系。我想这样做 SELECT c.*, (SELECT COUNT(*) FROM items i WHERE i.catId=c.id) AS itemCount FROM category c 假设我们有一个Hibernate POJO“类类别” 我的第一个问题是,我真的不能从那个查询中找到一个列表对象,对吗?我如何访问“itemCount”?因为没有类别。getItemCount() 第二,如何编写条件查询 谢谢这取决于您的环境和创建视图的
SELECT c.*,
(SELECT COUNT(*) FROM items i WHERE i.catId=c.id)
AS itemCount
FROM category c
假设我们有一个Hibernate POJO“类类别”
我的第一个问题是,我真的不能从那个查询中找到一个列表对象,对吗?我如何访问“itemCount”?因为没有类别。getItemCount()
第二,如何编写条件查询
谢谢这取决于您的环境和创建视图的能力。我将根据您的查询创建一个视图:
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
此外,还可以使用GROUPBY获得类似的结果,但这取决于列和表的架构
比如说:
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
SELECT c.*
,(SELECT COUNT(*) FROM items i WHERE i.catid = c.id) AS item_ct
FROM category c
2) 左加入,然后分组
总运行时间:36.320毫秒
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) 组,然后左键加入
总运行时间: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
作为主键。对于旧版本,必须在GROUPBY子句中列出所有非聚合列 我通常切换到
LEFT JOIN
,因为原始查询包含没有关联项的类别
items.catID
上的索引仅由1)使用,其中多个子查询可以获利。在其他查询中,顺序扫描速度更快:无论如何都必须读取这两个表。似乎这就是我一直在寻找的答案(进入POJO):
如果优化器为您的查询和原始查询生成相同的计划,我不会感到惊讶。请注意,您可能希望左连接为那些没有项目的类别获得
0
计数(这是原始语句所做的)@a_horse_,其名称为:是的,我也想到了左连接。我会检查计划者是否进行了优化……好吧,这个答案确实不是我问题的答案:)但不管怎样,items表的“id”和“catid”列是否有索引?@Seregwethrin:是的,与你要求的不完全一样。:)但可能对你还是有用的。我在测试用例中添加了一些关于索引使用的内容。我想创建一个视图,但我真的不想为每个计数、最大值、最小值或任何其他聚合函数或子查询创建一个视图。如果我只看一个大的视图,其中包括任何可能的视图,那么这就是一个性能损失。另外,我仍然不明白如何通过Hibernate POJO文件访问第二个示例中的ItemCount,因为它们不包含ItemCount(但是是的,第一个解决方案将包含ItemCount,但正如我之前所说的,这对我来说似乎不是一个聪明的解决方案)。再想一想,我可以设置“int ItemCount”吗属性转换为POJO文件,即使查询中不存在itemCount,它是否也能正常工作?(没有子查询)我只是尝试将一个视图映射到Hibernate,结果是一场灾难。。。因为视图没有键,Hibernate工具创建了两个类CategoryView和CategoryView,根据我读到的一些文章,这也是这种情况下的建议模式。现在我有3个类文件,Category(实际表),CategoryView和CategoryView。如果在Hibernate中没有更好的视图系统,我肯定不会选择这个解决方案。
@Formula(value="(SELECT COUNT(*) FROM Items i WHERE i.id = id)")
@Basic(fetch=FetchType.EAGER)
public Integer getItemCount() {
return this.taskCount;
}