如何在HQL中创建Distinct查询

时间:2008-11-04 23:17:39

标签: hibernate hql distinct

有没有办法在HQL中创建一个Distinct查询。通过使用“distinct”关键字或其他方法。我不确定distinct是否是HQL的有效关键字,但我正在寻找与SQL关键字“distinct”相当的HQL。

11 个答案:

答案 0 :(得分:121)

这是我们使用的一段hql。 (名称已更改为保护身份)

String queryString = "select distinct f from Foo f inner join foo.bars as b" +
                " where f.creationDate >= ? and f.creationDate < ? and b.bar = ?";
        return getHibernateTemplate().find(queryString, new Object[] {startDate, endDate, bar});

答案 1 :(得分:52)

值得注意的是,HQL中的distinct关键字不会直接映射到SQL中的distinct关键字。

如果在HQL中使用distinct关键字,则有时Hibernate将使用distinct SQL关键字,但在某些情况下,它将使用结果转换器来生成不同的结果。例如,当您使用这样的外部联接时:

select distinct o from Order o left join fetch o.lineItems

在这种情况下,无法在SQL级别过滤掉重复项,因此Hibernate在执行SQL查询后使用ResultTransformer过滤重复项

答案 2 :(得分:15)

下次做这样的事情

 Criteria crit = (Criteria) session.
                  createCriteria(SomeClass.class).
                  setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

 List claz = crit.list();

答案 3 :(得分:9)

您也可以将Criteria.DISTINCT_ROOT_ENTITY与Hibernate HQL查询一起使用。

示例:

Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();

答案 4 :(得分:4)

我遇到了结果变换器与HQL查询相结合的问题。我试过的时候

final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);

它不起作用。我必须像这样手动转换:

final List found = trans.transformList(qry.list());

使用Criteria API变换器工作正常。

答案 5 :(得分:3)

我的主查询在模型中看起来像这样:

@NamedQuery(name = "getAllCentralFinancialAgencyAccountCd", 
    query = "select distinct i from CentralFinancialAgencyAccountCd i")

我仍然没有得到我认为“明显”的结果。它们只是基于桌面上的主键组合而不同。

所以在DaoImpl我添加了一行更改并最终获得了我想要的“明显”回报。一个例子是,而不是看到00四次我现在只看到它一次。以下是我添加到DaoImpl的代码:

@SuppressWarnings("unchecked")
public List<CacheModelBase> getAllCodes() {

    Session session = (Session) entityManager.getDelegate();
    org.hibernate.Query q = session.getNamedQuery("getAllCentralFinancialAgencyAccountCd");
    q.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // This is the one line I had to add to make it do a more distinct query.
    List<CacheModelBase> codes;
    codes = q.list();
    return codes;       
}

我希望这有帮助!再一次,这可能只有在您遵循实现项目的服务,dao和模型类型的编码实践时才有效。

答案 6 :(得分:2)

假设您有一个客户实体映射到CUSTOMER_INFORMATION表,并且您希望获得客户的不同firstName列表。您可以使用以下代码段来获得相同内容。

Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();

我希望它有所帮助。所以这里我们使用group by而不是使用distinct关键字。

此前,当我想将其应用于多个列时,我发现很难使用distinct关键字。例如,我想得到不同的firstName列表,lastName然后group by就行了。在这种情况下,我很难使用distinct。

答案 7 :(得分:1)

您可以像这样在条件构建器中使用与众不同的关键字。

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Orders> query = builder.createQuery(Orders.class);
Root<Orders> root = query.from(Orders.class);
query.distinct(true).multiselect(root.get("cust_email").as(String.class));

并在模型类中创建字段构造器。

答案 8 :(得分:0)

我有一个Hibernate查询语言的答案,可以使用Distinct字段。 您可以使用* SELECT DISTINCT(TO_CITY)FROM FLIGHT_ROUTE *。 如果使用 SQL 查询,则返回String List。您不能通过实体类使用它返回值。 所以解决这类问题的答案是使用 HQL SQL

FROM FLIGHT_ROUTE F WHERE F.ROUTE_ID IN (SELECT SF.ROUTE_ID FROM FLIGHT_ROUTE SF GROUP BY SF.TO_CITY);

SQL 查询语句中获取DISTINCT ROUTE_ID并输入为List。 IN查询从IN(List)过滤掉不同的TO_CITY。

返回类型是实体Bean类型。 所以你可以在AJAX中使用它,例如 AutoComplement

可能一切正常

答案 9 :(得分:0)

如果您需要在select语句中为自定义DTO使用 new 关键字,并且需要与众不同的元素,请使用new之外的new,如下所示-

select distinct new com.org.AssetDTO(a.id, a.address, a.status) from Asset as a where ...

答案 10 :(得分:0)

您可以简单地添加GROUP BY而不是Distinct

@Query(value = "from someTableEntity where entityCode in :entityCode" +
            " group by entityCode, entityName, entityType")
List<someTableEntity > findNameByCode(@Param("entityCode") List<String> entityCode);