Будьте в спящем режиме Критерии API: получите n случайные строки

Для меня работали стилист и модификация Винса. Я хотел бы указать, что объяснение @ vince может быть не совсем точным.

Чтобы проверить гипотезу о том, что атрибут name declare-styleable, соответствующий имени пользовательского класса представления, позволяет нам получить доступ к пользовательскому атрибут без пространства имен Я изменил имя declare-styleable (пользовательское представление было названо TestViewFont:

<declare-styleable name="TextViewFont2">
    <attr name="font" format="integer"/>
</declare-styleable>

Затем я изменил вызов obtainStyledAttributes в пользовательском представлении, чтобы отразить это:

TypedArray ta = context.getTheme().obtainStyledAttributes(attrs, R.styleable.TextViewFont2, 0, 0);

Код все еще работает. Поэтому я не думаю, что это какая-то интроспекция declare-styleable класса, в котором он назван.

Таким образом, я возглавляю полагать, что любые пользовательские атрибуты могут использоваться для объявления стиля без обращения к пространству имен.

Независимо от того, спасибо всем парням помощи, он решил мою проблему.

18
задан Hadrien 11 May 2010 в 12:57
поделиться

5 ответов

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

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

45
ответ дан 30 November 2019 в 06:19
поделиться

Ответ @PSV Bhat является трудным при динамичной генерации Критериев. Вот решение, которое расширяется, в спящем режиме класс Порядка:

import org.hibernate.Criteria;
import org.hibernate.criterion.Order;

private void addOrderByToCriteria(Criteria criteria) {
    criteria.addOrder(Order.asc("foobar"));
    criteria.addOrder(ORDER_RANDOM);
}

private static final OrderRandom ORDER_RANDOM = new OrderRandom();

private static class OrderRandom extends Order {
    public OrderRandom() {
        super("", false);
    }
    @Override
    public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) {
        return "RANDOM()"; // or RAND() or whatever this is in your dialect
    }
}
0
ответ дан 30 November 2019 в 06:19
поделиться

Прежде всего, имейте в виду, что стандартного способа сделать это в 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, Criteria API в настоящее время не поддерживает ORDER BY Native SQL (см. HHH-2381), и в текущем состоянии для реализации этой возможности вам придется подклассифицировать класс Order. Это выполнимо, см. вопрос в Jira, но не доступно из коробки.

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

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

6
ответ дан 30 November 2019 в 06:19
поделиться

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

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

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

1
ответ дан 30 November 2019 в 06:19
поделиться

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

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

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

0
ответ дан 30 November 2019 в 06:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: