我想使用Spring數據JPA獲取隨機記錄。我正在使用@Query,但它需要很長時間。使用Spring數據獲取隨機記錄JPA
@Query("select que from Question que order by RAND()")
public List<Question> findRandamQuestions();
這是做同樣的有效方法嗎?請幫助!
我想使用Spring數據JPA獲取隨機記錄。我正在使用@Query,但它需要很長時間。使用Spring數據獲取隨機記錄JPA
@Query("select que from Question que order by RAND()")
public List<Question> findRandamQuestions();
這是做同樣的有效方法嗎?請幫助!
你可以做這個post fetch。
獲得所有問題的列表,只是從那些隨機的問題。
public List<Question> getRandomQuestions(List<Questions> questions, int numberOfQuestions) {
List<Question> randomQuestions = new ArrayList<>();
List<Question> copy = new ArrayList<>(questions);
SecureRandom rand = new SecureRandom();
for (int i = 0; i < Math.min(numberOfQuestions, questions.size()); i++) {
randomQuestions.add(copy.remove(rand.nextInt(copy.size()));
}
return randomQuestions;
}
或者,如果你的名單是真的大,你知道的ID事先,你可以做同樣的事情,只是獲取你所需要的問題的ID。
AFAIK在Spring Data中沒有對此的支持。恕我直言,你最好的行動方式是創建一個本地查詢,例如@Query(nativeQuery=true, value="SELECT * FROM question ORDER BY random() LIMIT 10")
使用PostgreSQL的原生random()
排序方法,或在您的數據庫中的一些等價物。
select que from Question que order by RAND()
的問題在於您的數據庫將在返回一個項目之前對所有記錄進行排序。所以它在大數據集中很昂貴。
便宜的方式來實現這一目標包括兩個步驟:
要做到這一點比如在MySQL中,你可以這樣做:
select count(*) from question;
// using any programming language, choose a random number between 0 and count-1 (let's save this number in rdn), and finally
select * from question LIMIT $rdn, 1;
好,但要做到這一點,春季數據,你需要創建一些原生查詢...
幸運的是,我們可以使用分頁來解決這個問題。在您的倉庫接口,創建方法(某些存儲庫有此無需將它定義):
Long count();
Page<Question> findAll(Pageable pageable);
而在你的服務,你可以通過用戶您通過以下方式庫:
public Question randomQuestion() {
Long qty = questionRepository.countAll();
int idx = (int)(Math.random() * qty);
Page<Question> questionPage = questionRepository.findAll(new PageRequest(idx, 1));
Question q = null;
if (questionPage.hasContent()) {
q = questionPage.getContent().get(0);
}
return q;
}
這是一個(a)它*完全*我所需要的,以及(b)谷歌和我無法發現任何其他遠程關閉的完美答案。但我認爲你有一個錯字:不應該「countAll()」是「count()」? – fivedogit