HQL:如何选择某些列不同的所有实体?
Posted
技术标签:
【中文标题】HQL:如何选择某些列不同的所有实体?【英文标题】:HQL: How to select all entities distinct by some column? 【发布时间】:2011-06-11 16:12:16 【问题描述】:一个简单的问题: 在此示例中,我需要检索所有对象,但这些对象必须具有不同的 msgFrom 字段。 当我使用
List<Message> list = getHibernateTemplate().find("select distinct m.msgFrom from Message m WHERE msgTo = ? AND msgCheck = 0", dinc);
我得到下一个错误:
java.lang.ClassCastException: java.lang.Integer cannot be cast to com.example.model.Message
我想这是因为 Hibernate 只检索一列,但我需要一个对象,而不是列。 我该怎么做? 我认为我可以只滚动一个逗号,即
List<Message> list = getHibernateTemplate().find("select distinct m.msgFrom, m.To, m.datetime, .......... from Message m WHERE msgTo = ? AND msgCheck = 0", dinc);
但是如果我这里有超过 20 个字段怎么办?有没有简单的解决办法?
谢谢!
【问题讨论】:
【参考方案1】:以下是示例查询:
select e from Message e
where e.msgFrom IN (select distinct m.msgFrom
from Message m
WHERE m.msgTo = ?
AND m.msgCheck = "0");
或者,您也可以使用 Criteria API。
【讨论】:
但是有没有使用 Criteria API 的示例? Criteria API 如何构建动态查询并减少运行时故障 - ibm.com/developerworks/java/library/j-typesafejpa 这确实有效。我找到的唯一可接受的解决方案。 但是使用此解决方案,您不会从每个 msgFrom 获得唯一消息【参考方案2】:您也可以同时使用 Criteria 和 Projection :
Criteria criteria = session.createCriteria( MyEntity.class );
criteria.setProjection( Projections.distinct( Projections.property( "id" ) ) );
希望对某人有所帮助。
【讨论】:
谢谢。如果您希望结果包含整个 Message 类及其所有属性集怎么办?【参考方案3】:试试这个,它对我有用:
SELECT FROM YourTableName
WHERE somecolumnName=condition
GROUP BY yourDistinctColumnName
【讨论】:
它可以工作,并且可以更清楚地作为 SELECT FROM Object o WHERE o.propCondition = condition GROUP BY o.propDistinct【参考方案4】:我得到了 Hibernate Query Language to use Distinct fields 的答案。您可以使用SELECT DISTINCT(TO_CITY) FROM FLIGHT_ROUTE
。如果使用 SQL 查询,则返回字符串列表。您不能通过实体类使用它返回值。因此,解决此类问题的答案是将 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
并作为列表输入。并且 IN 查询从IN
(列表)中过滤出不同的TO_CITY
。
返回类型是Entity Bean类型。所以你可以在 AJAX 中,比如 AutoComplement。
一切都会好起来的
【讨论】:
【参考方案5】:Hibernate 标准很容易选择不同的结果。 如果您希望在投影结果中返回单个结果,您可能需要使用:
Criteria criteria = session.createCriteria(Message.class);
criteria.setProjection(Projections.distinct(Projections.property("msgFrom ")));
List<String> msgFromList = criteria.list();
如果您希望结果包含整个 Message 类及其所有属性集,您可以使用 Hibernate result Transformer,
Criteria criteria = session.createCriteria(Message.class);
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List<Message> messages = criteria.list();
但它是根据根实体进行过滤的。
或者
Criteria criteria = session.createCriteria(Message.class);
ProjectionList projection = Projections.projectionList();
projection.add(Projections.distinct(Projections.property("msgFrom")));
//Add as many columns as you want using Projection
projection.add(Projections.property("msgTo"));
criteria.setProjection(projection);
criteria.setResultTransformer(Transformers.aliasToBean(Message.class));
List<String> msgFromList = criteria.list();
根据您的问题,第一个解决方案给出正确的输出。
【讨论】:
【参考方案6】:作为@APC 响应
它有效,它可以更清晰
SELECT FROM Object o
WHERE o.propCondition = condition
GROUP BY o.propDistinct
【讨论】:
【参考方案7】:如果你想用 DISTINCT 获得一个完整的实体,你可以使用 Projections.Entity
Criteria.SetProjection(
Projections.Distinct(Projections.Entity(typeof(YourEntityHere), "this")));
“this”表示根实体。
【讨论】:
以上是关于HQL:如何选择某些列不同的所有实体?的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate HQL:当且仅当所有子实体都具有相同值的属性时,如何选择父实体?