2010-05-11 17 views
18

nie mogę dowiedzieć się, jak pobrać n losowe wierszy z instancji kryteria:Hibernate Criteria API: get n losowe wierszy

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

co wtedy? Nie mogę znaleźć żadnego dokumentu z API Criteria

Czy to znaczy, że powinienem użyć HQL zamiast tego?

Thanx!

EDIT: mam liczbę wierszy przez:

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

Jak pobrać n losowe wierszy z indeksów pomiędzy 0 a max? Thx again!

Odpowiedz

43

W rzeczywistości jest to możliwe dzięki Kryteriom i odrobiną poprawek.Oto jak:

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

dowolny Restrictions.sqlRestriction doda słowa kluczowego 'i'; więc aby unieważnić jego działanie, dodamy stan obojętny i wstrzykniemy funkcję rand().

+1

To było wygodne i pomogło mi! – Nischal

+1

Nie zwraca unikalnych rekordów ... – Imran

+2

Jaki jest cel 1 = 1 w ograniczeniach sql. Dostaję z tym odpowiednią wydajność, a bez tego pojawia się błąd –

0

Nie można efektywnie pobrać losowych wierszy, przepraszam. Hibernate może wykonywać tylko to, co robi SQL, a losowe pobieranie wierszy po prostu nie jest częścią jakiejkolwiek standardowej implementacji SQL, którą znam - w rzeczywistości jest to według mojej wiedzy, nie będącą częścią JAKIEGOKOLWIEK SQL, o którym wiem (każdy proszę mnie oświecić).

A ponieważ Hibernacja jest programem odwzorowującym O/R, a nie maszyną cudowną, może wykonywać tylko to, co obsługuje podstawowa baza danych.

Jeśli masz znany numer z rosnącymi numerami i znasz początek i koniec, możesz wygenerować losową liczbę na komputerze i poprosić o ten wiersz.

+0

Są to doskonałe rozważania, chociaż efektywność nie była jego główną troską. – fabspro

+0

Mysql robi zamówienie według rand() –

1

Interfejs API Criteria nie oferuje tego. W MySQL można jednak użyć ORDER BY RAND() LIMIT n, gdzie n reprezentuje liczbę losowych wierszy, które chcesz pobrać.

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

Rzeczywiście trzeba wykonać to jako HQL.

6

Przede wszystkim należy pamiętać, że nie ma standardowego sposobu wykonania tego w SQL, każdy silnik bazy danych używa własnej zastrzeżonej składni . MySQL, SQL, aby uzyskać 5 losowe wierszy byłoby:

SELECT column FROM table 
ORDER BY RAND() 
LIMIT 5 

I można napisać tej kwerendy w HQL ponieważ zamówienie przez klauzuli w HQL zostanie przerzucony na bazie więc można użyć dowolnej funkcji .

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

Jednak w przeciwieństwie do HQL, Criteria API aktualnie nie obsługuje BY Native SQL (patrz HHH-2381) oraz w obecnym stanie, trzeba by podklasy klasy Order do realizacji tej funkcji. Jest to wykonalne, patrz problem Jira, ale nie jest dostępny po wyjęciu z pudełka.

Tak więc, jeśli naprawdę potrzebujesz tego zapytania, moim zaleceniem byłoby użycie HQL. Pamiętaj, że nie będzie przenośny.

Inni czytelnicy mogą chcieć sprawdzić wpis SQL to Select a random row from a database table, aby zobaczyć, jak zaimplementować to z MySQL, PostgreSQL, Microsoft SQL Server, IBM DB2 i Oracle.

+0

Hibernate mówi mi, że nie ma takiej funkcji jak "RAND", używając pg @ java7, hmm ... co zrobiłem źle? -> jego losowe() w przypadku pg, przepraszam, że przeszkadzam – Chris

Powiązane problemy