休眠条件中的子选择
Posted
技术标签:
【中文标题】休眠条件中的子选择【英文标题】:Sub-Select In hibernate criteria 【发布时间】:2017-04-17 12:30:04 【问题描述】:我有一个带有列名的 sql 表 A
name, id1, id2, val1
还有一个带有列名的表 B
id1, id2, key1, key2
这是我的 sql 查询
SELECT
v1.id1,
v1.id2
FROM (
SELECT
A.id1,
A.id2,
min(val1) AS x
FROM A
JOIN B ON A.id1 = B.id1 AND A.id2 = B.id2
GROUP BY A.id1, A.id2
) AS v1
WHERE v1.x > 10
使用 DetachedCriteria 我能够形成子查询
DetachedCriteria subCriteria = DetachedCriteria.forClass(A_model.class);
subCriteria.createAlias("b", "b_model");
subCriteria.setProjection(Projections.projectionList()
.add(Projections.groupProperty("id1"))
.add(Projections.groupProperty("id2"))
.add(Projections.min("val1"),"x");
但我在创建外部查询时遇到了困难。
任何建议我如何为上述 SQL 创建条件?
感谢期待。
【问题讨论】:
标准查询适用于实体,而不是表。我们不知道实体长什么样。 @JBNizet 我已经为我想要的表和 sql 提供了列。除此之外,您还需要更多信息吗?您能否建议通过标准进行子选择的通用解决方案?(随意假设任何相应的实体结构) 【参考方案1】:Hibernate 暂时不支持from
子句中的子选择。但是,您可以使用HAVING
子句以更简单、更有效的形式重写您的查询:
SELECT A.id1, A.id2,
FROM A JOIN B ON A.id1 = B.id1 AND A.id2 = B.id2
GROUP BY A.id1, A.id2
HAVING min(val1) > 10
上述查询可以轻松移植到 HQL 或 Criteria。
【讨论】:
【参考方案2】:考虑为您需要的数据创建一个视图:
create view A_B_BY_ID1_AND_ID2 as
select A.id1,
A.id2,
min( val1 ) as x
from A
join B on A.id1 = B.id1 and A.id2 = B.id2
group by A.id1,
A.id2
然后创建一个 DTO 来表示这个数据:
@Entity(table="A_B_BY_ID1_AND_ID2")
@Data //are you on board with lombok?
public class ABById1AndId2
@Column
private int x;
@Column
private int id1;
@Column
private int id2;
然后像其他任何东西一样访问它:
session.createCriteria(ABById1AndId2.class).add(Restrictions.gt("x", 10)).list();
【讨论】:
【参考方案3】:HQL 和 Criteria 对象都不支持从 Select 中选择。这里的解决方案是命名查询。
@NamedNativeQueries(
@NamedNativeQuery(
name = "findV1",
query = "SELECT
v1.id1,
v1.id2
FROM (
SELECT
A.id1,
A.id2,
min(val1) AS x
FROM A
JOIN B ON A.id1 = B.id1 AND A.id2 = B.id2
GROUP BY A.id1, A.id2
) AS v1
WHERE v1.x > 10"
)
)
【讨论】:
以上是关于休眠条件中的子选择的主要内容,如果未能解决你的问题,请参考以下文章