Criteria.DISTINCT_ROOT_ENTITY vs Projections.distinct

我对Hibernate来说很新。 我发现我们可以用以下两种不同的方法得到不同的结果。 有谁能告诉我他们之间有什么区别? 何时使用其他的?

Projections.distinct(Projections.property("id")); 

VS

 criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); 

虽然类似的名字,用法是不同的。

I. Projections.distinct(Projections.property("id"));

这个语句将被翻译成SQL语句。 它将被传递给数据库引擎并作为SQL DISTINCT执行。 看到:

  • 17.9。 预测,聚合和分组

所以这个例子:

 List results = session.createCriteria(Cat.class) .setProjection( Projections.projectionList() .add( Projections.distinct(Projections.property("id")) ) ) .list(); 

会看起来像:

 SELECT DISTINCT(cat_id) FROM cat_table 

II。 criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

这个声明是事后执行 。 一旦来自数据库引擎的SQL查询被返回,Hibernate会迭代结果集,将其转换成我们实体的列表。

但总是需要吗? 不,大部分这是不需要的。

唯一的情况是,当我们必须使用它的时候,如果查询中有一个关联 – joinone-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()select不同的属性,在你的情况下通过标识符