我想使用Spring数据JPA获取随机记录。我正在使用@Query。但这需要很长时间。
@Query("select que from Question que order by RAND()")
public List<Question> findRandamQuestions();
这样做的有效方法是什么?请帮忙!
答案 0 :(得分:15)
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;
好的,但要在spring数据中执行此操作,您需要创建一些本机查询...
幸运的是,我们可以使用分页来解决这个问题。在您的存储库接口中,创建方法(某些存储库具有此功能而无需定义它):
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;
}
答案 1 :(得分:3)
你可以在获取后进行此操作。
获取所有问题的清单,然后从中获取随机问题。
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。
答案 2 :(得分:0)
AFAIK在Spring Data中不支持此功能。恕我直言,你最好的做法是创建一个原生查询,例如@Query(nativeQuery=true, value="SELECT * FROM question ORDER BY random() LIMIT 10")
使用PostgreSQL的本地random()
排序方法,或者数据库中的某些等效方法。