使用 Hibernate Criteria 获取具有最大 id 的记录
Posted
技术标签:
【中文标题】使用 Hibernate Criteria 获取具有最大 id 的记录【英文标题】:Get record with max id, using Hibernate Criteria 【发布时间】:2011-04-23 10:35:43 【问题描述】:使用Hibernate 的Criteria API,我想在给定列的最大值的表中选择记录。
我尝试将Projections、creating an alias 用于max(colunName)
,然后在restrictions.eq()
中使用它,但它一直告诉我“无效号码”。
使用 Hibernate 的正确方法是什么?
【问题讨论】:
【参考方案1】:完全使用分离标准(因为我喜欢在没有会话的情况下构建分离标准)
DetachedCriteria maxQuery = DetachedCriteria.forClass(Foo.class)
.setProjection( Projections.max("id") );
DetachedCriteria recordQuery = DetachedCriteria.forClass(Foo.class)
.add(Property.forName("id").eq(maxId) );
【讨论】:
【参考方案2】: 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);
【讨论】:
【参考方案3】:更清洁的解决方案也是:
DetachedCriteria criteria = DetachedCriteria.forClass(Foo.class).setProjection(Projections.max("id"));
Foo fooObj =(Foo) criteria.getExecutableCriteria(getCurrentSession()).list().get(0);
【讨论】:
【参考方案4】:我发现同时使用 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语句。【参考方案5】:
对于休眠中的max()
函数:
criteria.setProjection(Projections.max("e.encounterId"));
【讨论】:
我认为这只会返回 meetId 而不是记录对象。【参考方案6】:使用
addOrder(Order.desc("id"))
只获取第一个结果:)
【讨论】:
这很糟糕,因为您将整个列表从数据库中取出,然后丢弃所有其他记录。如果您有一张大桌子,那就不是很好了! 不,我说的是获取第一个,这可能是“SELECT ... LIMIT 1”之类的东西(抱歉,很久没有使用hibernate了)。您所说的是获取几个,并且只使用第一个;它们是不同的东西。【参考方案7】:您可以使用DetachedCriteria
来表达子查询,如下所示:
DetachedCriteria maxId = DetachedCriteria.forClass(Foo.class)
.setProjection( Projections.max("id") );
session.createCriteria(Foo.class)
.add( Property.forName("id").eq(maxId) )
.list();
参考文献
Hibernate 核心参考指南 15.8. Detached queries and subqueries【讨论】:
我用过,但不满意的是:它需要运行两个查询,再次感谢 man @AmrFaisal 请在下面查看我的回答,了解如何使用单个查询执行此操作。【参考方案8】:HQL:
from Person where person.id = (select max(id) from Person)
未经测试。您的数据库需要了解 where 子句中的子选择。
懒得去发现这样的子选择是否/如何用标准 api 来表达。当然,您可以执行两个查询:首先获取最大 id,然后获取具有该 id 的实体。
【讨论】:
你是个好人,我确实使用了第二个选项,使用了两个查询,但我正在搜索是否可以使用标准 api 来完成 :)以上是关于使用 Hibernate Criteria 获取具有最大 id 的记录的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate Criteria API:获取 n 个随机行
如何从 Hibernate Criteria API 获取 SQL(*not* 用于日志记录)