Criteria.DISTINCT_ROOT_ENTITY 与 Projections.distinct
Posted
技术标签:
【中文标题】Criteria.DISTINCT_ROOT_ENTITY 与 Projections.distinct【英文标题】:Criteria.DISTINCT_ROOT_ENTITY vs Projections.distinct 【发布时间】:2014-10-21 14:40:35 【问题描述】:我对 Hibernate 很陌生。我发现我们可以使用以下两种不同的方式获得不同的结果。谁能告诉我它们之间有什么区别?什么时候使用一个而不是另一个?
Projections.distinct(Projections.property("id"));
对
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
【问题讨论】:
【参考方案1】:虽然名称相似,但用法不同。
我。 Projections.distinct(Projections.property("id"));
这条语句将被翻译成 SQL 语句。它将传递给 DB Engine 并作为 SQL DISTINCT
执行。见:
例如这个例子:
List results = session.createCriteria(Cat.class)
.setProjection( Projections.projectionList()
.add( Projections.distinct(Projections.property("id")) )
)
.list();
看起来像:
SELECT DISTINCT(cat_id) FROM cat_table
二。 criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
此语句事后执行。一旦从 DB 引擎返回 SQL 查询,Hibernate 就会迭代结果集以将其转换为我们的实体列表。
但它总是需要吗?不,大多数情况下这不是必需的。
唯一的情况,当我们必须使用它时,如果查询中有关联 - 加入
one-to-many
结束。
因为如果我们确实有一个 cat
及其两个 kittens
,这将返回 两 行,而 cat
只有一个:
SELECT cat.*, kitten.*
FROM cat_table as cat
INNER JOIN kitten_table kitten ON kitten.cat_id = cat.cat_id
所以,criteriaQuery
末尾的声明:
... // criteriaQuery joining root and some one-to-many
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
将导致列表中只有一只猫。
【讨论】:
非常感谢您的明确回答。解释得很好。我几乎读完了Beginning Hibernate一书,但我仍然无法弄清楚Criteria.DISTINCT_ROOT_ENTITY。你用一个例子的回答让我很清楚。 我有一个疑问,你怎么能在它返回的第一个示例中创建类,而不仅仅是 id,你知道我的意思吗?谢谢。 我们可以使用 distinct id 并通过 HQL 使用它来从类中获取不同的行,但我认为这在性能方面不是一个好主意。 但是只有一只猫会同时拥有两只小猫吗? 我知道这已经很老了,但你能解释一下 DISTINCT_ROOT_ENTITY 在实际 SQL 术语中的作用吗?您在回答中描述它的方式是“您有一行 A,它是 1-n 并导致两行 B,您应用 DISTINCT_ROOT_ENTITY 并且它神奇地导致一行 B” - 如何?老实说,我很困惑如何在我正在构建的查询中复制它(与 java 无关)【参考方案2】:来自文档: DISTINCT_ROOT_ENTITY 每行结果都是根实体的一个不同实例
distinct() 按属性选择不同的,在你的情况下按标识符
【讨论】:
感谢您的回复。我理解第二行,但由于缺乏对根实体的了解,我没有完全理解第一行。还是很有帮助的。以上是关于Criteria.DISTINCT_ROOT_ENTITY 与 Projections.distinct的主要内容,如果未能解决你的问题,请参考以下文章