休眠条件 API:获取 n 个随机行

2022-09-02 11:30:00

我无法弄清楚如何从条件实例中获取n个随机行:

Criteria criteria = session.createCriteria(Table.class);
criteria.add(Restrictions.eq('fieldVariable', anyValue));
...

然后呢?我找不到任何带有标准 API 的文档

这是否意味着我应该改用 HQL?

感恩节!

编辑:我通过以下方式获得行数:

int max = criteria.setProjecxtion(Projections.rowCount()).uniqueResult();

如何获取索引在 0 到 max 之间的 n 个随机行?又是一次!


答案 1

实际上,通过标准和一点点调整是可能的。操作方法如下:

Criteria criteria = session.createCriteria(Table.class);
criteria.add(Restrictions.eq("fieldVariable", anyValue));
criteria.add(Restrictions.sqlRestriction("1=1 order by rand()"));
criteria.setMaxResults(5);
return criteria.list();

任何限制.sqlRestriction将添加关键字“and”;因此,为了抵消其效果,我们将添加一个虚拟条件并注入我们的rand()函数。


答案 2

首先,请注意,在SQL中没有标准的方法可以做到这一点,每个数据库引擎都使用自己的专有语法1。使用MySQL,获取5个随机行的SQL语句将是:

SELECT column FROM table
ORDER BY RAND()
LIMIT 5

您可以在 HQL 中编写此查询,因为 HQL 中的 order by 子句已传递到数据库,因此您可以使用任何函数。

String query = "SELECT e.attribute FROM MyEntity e ORDER BY RAND()";
Query q = em.createQuery(query);
q.setMaxResults(5);

但是,与 HQL 不同,Criteria API 当前不支持 ORDER BY Native SQL(请参阅 HHH-2381),并且在当前状态下,您必须对该类进行子类类才能实现此功能。这是可行的,请参阅 Jira 问题,但不是开箱即用的。Order

因此,如果您确实需要此查询,我的建议是使用 HQL。请记住,它不会是便携式的。

1 其他读者可能希望查看 POST SQL 以从数据库表中选择随机行,了解如何使用 MySQL、PostgreSQL、Microsoft SQL Server、IBM DB2 和 Oracle 来实现这一点。


推荐