使用 Spring 数据 JPA 获取随机记录

Posted

技术标签:

【中文标题】使用 Spring 数据 JPA 获取随机记录【英文标题】:Fetch random records using Spring data JPA 【发布时间】:2014-08-08 08:57:36 【问题描述】:

我想使用 Spring data JPA 获取随机记录。我也在使用@Query。但这需要很长时间。

@Query("select que from Question que order by RAND()")
public List<Question> findRandamQuestions();

什么是做同样的有效方法?请帮忙!

【问题讨论】:

【参考方案1】:

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 Data 中执行此操作,您需要创建一些本机查询...

幸运的是,我们可以使用分页来解决这个问题。在您的存储库接口中,创建方法(某些存储库具有此功能,无需定义):

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) Google 和我无法找到任何其他远程关闭的东西。但我认为你有一个错字:“countAll()”不应该是“count()”吗? 高五... 迄今为止对该主题的最佳解释。感谢您花时间分享结果。对于像我这样的新手来说,它超级容易理解这个概念。 new PageRequest() 现在已弃用。用户 PageRequest.of(idx, 1) 作为参数而不是【参考方案2】:

您可以获取此帖子。

获取所有问题的列表,然后从中获取随机问题。

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。

【讨论】:

【参考方案3】:

AFAIK 在 Spring Data 中不支持此功能。恕我直言,您最好的做法是创建一个本机查询,例如@Query(nativeQuery=true, value="SELECT * FROM question ORDER BY random() LIMIT 10") 使用 PostgreSQL 的原生 random() 排序方法,或在您的数据库中使用一些等效方法。

【讨论】:

以上是关于使用 Spring 数据 JPA 获取随机记录的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring Data JPA 获取两个日期之间的记录

在 Spring JPA 中删除实体

如何使用 Spring 和 JPA 设置多个数据源

基于Spring Boot,使用JPA动态调用Sql查询数据

使用spring data jpa删除数据库记录时出错

spring data JPA忽略查询方法上的fetchmode