我对Hibernate还比较陌生。我发现我们可以使用以下两种不同的方式获得不同的结果。有人能告诉我它们之间的区别吗?何时使用其中一种而不是另一种?
Projections.distinct(Projections.property("id"));
对抗
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
我对Hibernate还比较陌生。我发现我们可以使用以下两种不同的方式获得不同的结果。有人能告诉我它们之间的区别吗?何时使用其中一种而不是另一种?
Projections.distinct(Projections.property("id"));
对抗
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
虽然名称相似,但使用方式不同。
Projections.distinct(Projections.property("id"));
该语句将被翻译为SQL语句,并传递给DB引擎作为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);
这条语句是在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)
这将导致一个只有一只猫的列表。
来自文档: DISTINCT_ROOT_ENTITY 结果中的每一行都是根实体的唯一实例
distinct() 按属性选择唯一值,对于您的情况是按标识符选择唯一值