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

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

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

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

【问题讨论】:

    标签: spring hibernate jpa spring-data spring-data-jpa


    【解决方案1】:

    select que from Question que order by RAND() 的问题是您的数据库将在返回一项之前订购所有记录。所以在大型数据集中它很昂贵。

    实现此目标的更便宜的方法包括两个步骤:

    1. 查找要从中选择一个的记录总数。
    2. 在此套装中随机获得一件物品。

    以 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() 排序方法,或在您的数据库中使用一些等效方法。

      【讨论】:

        猜你喜欢
        • 2018-07-20
        • 2011-01-27
        • 2017-10-04
        • 2019-06-18
        • 1970-01-01
        • 2020-02-13
        • 2018-06-06
        • 2011-07-17
        • 2017-06-05
        相关资源
        最近更新 更多