JPA:选择随机行

时间:2014-01-29 13:10:07

标签: java jpa jpql named-query

这是我的JPA ENTITY

@Entity
@NamedQueries({  
        @NamedQuery(name = "Question.randQuestion", query = "SELECT q FROM Question AS q ORDER BY     RANDOM")
})
@Table(name = "questions")
public class Question implements Serializable {
.....
}

问题是:

eclipse给了我这个namedQuery的错误。它说: “识别变量'RANDOM'未在FROM子句中定义”

我也尝试过使用RAND()而不是RANDOM以及NEWID()。

感谢。

3 个答案:

答案 0 :(得分:6)

要获得随机行,首先获取总问题列表并获取任何一个。

public Question  getRandomQuestion(EntityManager em) {
  Query countQuery = em.createNativeQuery("select count(*) from Question");
  long count = (Long)countQuery.getSingleResult();

  Random random = new Random();
  int number = random.nextInt((int)count);

  Query selectQuery = em.createQuery("select q from Question q");
  selectQuery.setFirstResult(number);
  selectQuery.setMaxResults(1);
  return (Question)selectQuery.getSingleResult();
}

注意:您可能需要实现一个逻辑,以便在多次调用方法时避免重复。

答案 1 :(得分:1)

我必须解决此问题的特定情况,即我必须从一组符合特定输入条件的记录中选择随机记录。该解决方案还必须支持极限。我从下面的假设开始描述我的解决方案。

假设:

  
      
  • 使用一组标准作为输入,可以对org.springframework.data.querydsl.QueryDslPredicateExecutor<T>.count(Predicate predicate)方法支持的符合选择标准的记录数进行计数。

  •   
  • 页面的索引为零。

  •   
  • 可以请求org.springframework.data.domain.PageRequest(int page, int size)方法支持的特定页面。

  •   

算法

  
      
  1. 对符合输入条件的所有记录进行计数。

  2.   
  3. 根据计数和指定的限制计算页面总数。

  4.   
  5. 生成范围为[0,总页数]的随机页面索引。

  6.   
  7. 请求具有上一步生成的索引的页面。

  8.   
  9. 在返回的页面中随机播放元素。

  10.   

代码

Long totalRecords = someRepository.count(somePredicate);
Long totalPages =
    (totalRecords % someLimit == 0)
        ? (totalRecords / someLimit)
        : ((totalRecords / someLimit) + 1);
int pageIndex = (int) (Math.random() * totalPages);

PageRequest pageRequest = new PageRequest(pageIndex, someLimit);
Page<T> somePage = someRepository.findAll(somePredicate, pageRequest);
List<T> someList;
if (somePage.getTotalElements() > 0) {
  someList = new ArrayList<>(somePage.getContent());
} else {
  someList = new ArrayList<>();
}

Collections.shuffle(someList);

第二个改组是确保页面内的记录也被随机化。此解决方案的一般情况是没有条件,因此必须count()时不使用predicate来调用,从而获得表中所有行的计数。

答案 2 :(得分:0)

据我了解,您想从表格中选择随机问题。您更愿意使用WHERE子句,并在代码中提供一些参数,例如:

SELECT q FROM Question AS q WHERE id = :id

然后在创建查询的代码中,您必须生成要选择的随机ID:

query.setParam("id", getRandomId());

要获得随机ID,您可能需要查询来自数据库的行数并使用java.util.Random.nextInt(rowsCount)(当然,如果所有ID都在那里)。

顺便说一下,类似的内容在这里描述:http://www.shredzone.de/cilla/page/53/how-to-fetch-a-random-entry-with-hibernate.html