Hibernate Criteria API: получить n случайных строк - PullRequest
18 голосов
/ 11 мая 2010

Я не могу понять, как извлечь n случайных строк из экземпляра критерия:

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

Тогда что? Я не могу найти документ с Criteria API

Значит ли это, что я должен использовать вместо HQL?

Thanx!

РЕДАКТИРОВАТЬ: я получаю количество строк по:

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

Как мне выбрать n случайных строк с индексами от 0 до макс? Спасибо еще раз!

Ответы [ 4 ]

45 голосов
/ 13 мая 2010

На самом деле это возможно с критериями и небольшим количеством настроек. Вот как:

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();

Любой Restrictions.sqlRestriction добавит ключевое слово 'and'; чтобы свести на нет его эффект, мы добавим фиктивное условие и добавим нашу функцию rand ().

6 голосов
/ 11 мая 2010

Прежде всего, имейте в виду, что в SQL не существует стандартного способа сделать это, каждый механизм базы данных использует свой собственный синтаксис 1 . С MySQL оператор SQL для получения 5 случайных строк будет:

SELECT column FROM table
ORDER BY RAND()
LIMIT 5

И вы могли бы написать этот запрос на HQL, потому что предложение order by в HQL передается в базу данных , поэтому вы можете использовать любую функцию.

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

Однако, в отличие от HQL, API Criteria в настоящее время не поддерживает ORDER BY Native SQL (см. HHH-2381 ), и в текущем состоянии вам придется создать подкласс Order класс для реализации этой функции. Это выполнимо, обратитесь к проблеме Jira, но не доступно из коробки.

Так что, если вам действительно нужен этот запрос, я рекомендую использовать HQL. Просто имейте в виду, что он не будет портативным.

1 Другие читатели могут захотеть проверить сообщение SQL для выбора случайной строки из таблицы базы данных , чтобы узнать, как реализовать это с MySQL, PostgreSQL, Microsoft SQL Server, IBM DB2 и Oracle.

1 голос
/ 11 мая 2010

Criteria API не предоставляет возможности для этого. Однако в MySQL вы можете использовать ORDER BY RAND() LIMIT n для этого, где n представляет количество случайных строк, которые вы хотите получить.

SELECT col1, col2, col3 FROM tbl ORDER BY RAND() LIMIT :n

Вам действительно нужно выполнить его как HQL.

0 голосов
/ 11 мая 2010

Вы не можете эффективно выбирать случайные строки, извините. Hibernate может делать только то, что делает SQL, и случайная выборка строк просто не является частью какой-либо стандартной реализации SQL, которую я знаю - на самом деле, насколько я знаю, это не часть ЛЮБОГО SQL, о которой я знаю (кто-нибудь, пожалуйста, сообщите мне).

А поскольку Hibernate является устройством отображения O / R, а не чудом, он может делать только то, что поддерживает базовая база данных.

Если у вас есть известное поле с возрастающими числами и вы знаете начало и конец, вы можете сгенерировать случайное число на компьютере и запросить эту строку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...