2014-06-18 3 views
9

Spring 데이터 JPA를 사용하여 임의의 레코드를 가져 오려고합니다. 같은 것을 위해 @Query를 사용했습니다. 그러나 오랜 시간이 걸립니다.Spring 데이터를 사용하여 임의의 레코드를 가져옵니다. JPA

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

동일한 작업을 수행하는 효율적인 방법은 무엇입니까?

답변

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를 가져올 수 있습니다.

0

AFAIK 스프링 데이터에서는 이에 대한 지원이 없습니다. IMHO, 최선의 행동 강령은 네이티브 검색어를 만드는 것입니다. @Query(nativeQuery=true, value="SELECT * FROM question ORDER BY random() LIMIT 10") PostgreSQL의 네이티브 random() 정렬 방법을 사용하거나 일부 DB에 해당하는 정렬 방법을 사용하십시오.

5

select que from Question que order by RAND()의 문제점은 DB가 하나의 항목을 반환하기 전에 모든 레코드를 정렬한다는 것입니다. 따라서 대형 데이터 세트에서는 비용이 많이 듭니다. 당신이 하나를 선택 곳에서 레코드의

  1. 찾기 총 :

    이 목표를 달성하기 위해 싼 방법은 두 단계로 구성되어 있습니다.

  2. 이 세트의 임의 항목 하나를 가져옵니다. 다행히도 ...

    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; 
    

    이 좋아,하지만 봄의 데이터에서 일부 기본 쿼리를 만들 필요가 있다고 할 :

는 MySQL의 예를 들면, 당신이 할 수있는 것을해야 할 일 우리는이를 해결하기 위해 페이지 매김을 사용할 수 있습니다.

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; 
} 
+0

이 하나입니다 (a) 정확히 * 내가 필요로하는 것, (b) Google과 내가 원격으로 닫을 수없는 것을 찾을 수 없었던 완벽한 해답. 하지만 당신은 오타가 있다고 생각합니다. "countAll()"이 "count()"가되어서는 안됩니까? – fivedogit

관련 문제