【发布时间】:2011-04-23 10:35:43
【问题描述】:
使用Hibernate 的Criteria API,我想在给定列的最大值的表中选择记录。
我尝试将Projections、creating an alias 用于max(colunName),然后在restrictions.eq() 中使用它,但它一直告诉我“无效号码”。
使用 Hibernate 的正确方法是什么?
【问题讨论】:
使用Hibernate 的Criteria API,我想在给定列的最大值的表中选择记录。
我尝试将Projections、creating an alias 用于max(colunName),然后在restrictions.eq() 中使用它,但它一直告诉我“无效号码”。
使用 Hibernate 的正确方法是什么?
【问题讨论】:
完全使用分离标准(因为我喜欢在没有会话的情况下构建分离标准)
DetachedCriteria maxQuery = DetachedCriteria.forClass(Foo.class)
.setProjection( Projections.max("id") );
DetachedCriteria recordQuery = DetachedCriteria.forClass(Foo.class)
.add(Property.forName("id").eq(maxId) );
【讨论】:
Date maxDateFromDB = null;
Session session = (Session) entityManager.getDelegate();
//Register is and Entity and assume maxDateFromDB is a column.
//Status is another entity with Enum Applied.
//Code is the Parameter for One to One Relation between Register and Profile entity.
Criteria criteria = session.createCriteria(Register.class).setProjection(Projections.max("maxDateFromDB") )
.add(Restrictions.eq("status.id", Status.Name.APPLIED.instance().getId()));
if(code != null && code > 0) {
criteria.add(Restrictions.eq("profile.id", code));
}
List<Date> list = criteria.list();
if(!CollectionUtils.isEmpty(list)){
maxDateFromDB = list.get(0);
}
【讨论】:
更清洁的解决方案也是:
DetachedCriteria criteria = DetachedCriteria.forClass(Foo.class).setProjection(Projections.max("id"));
Foo fooObj =(Foo) criteria.getExecutableCriteria(getCurrentSession()).list().get(0);
【讨论】:
我发现同时使用 addOrder 和 setMaxResults 对我有用。
Criteria c = session.createCriteria(Thingy.class);
c.addOrder(Order.desc("id"));
c.setMaxResults(1);
return (Thingy)c.uniqueResult();
使用 MySQL 方言,这会生成一个类似这样的 SQL 准备语句(剪掉一些字段):
select this_.id ... from Thingy this_ order by this_.id desc limit ?
我不确定这个解决方案是否对 MySQL 以外的方言有效。
【讨论】:
order by和limit一般是slower然后是max/min的sql语句。
对于休眠中的max()函数:
criteria.setProjection(Projections.max("e.encounterId"));
【讨论】:
使用
addOrder(Order.desc("id"))
只获取第一个结果:)
【讨论】:
您可以使用DetachedCriteria 来表达子查询,如下所示:
DetachedCriteria maxId = DetachedCriteria.forClass(Foo.class)
.setProjection( Projections.max("id") );
session.createCriteria(Foo.class)
.add( Property.forName("id").eq(maxId) )
.list();
【讨论】:
HQL:
from Person where person.id = (select max(id) from Person)
未经测试。您的数据库需要了解 where 子句中的子选择。
懒得去发现这样的子选择是否/如何用标准 api 来表达。当然,您可以执行两个查询:首先获取最大 id,然后获取具有该 id 的实体。
【讨论】: