我有跟随MySql的相关代码(ORDER BY RAND())。我想知道是否有hibernate HQL替代它(admin是boolean tag,表明用户是管理员)。这是工作代码:
public long getRandomAdmin() {
Session session = getSession();
Query selectQuery = session.createSQLQuery("SELECT user_id FROM users WHERE admin = '1' ORDER BY RAND()");
selectQuery.setMaxResults(1);
List<BigInteger> list = null;
try {
list = selectQuery.list();
} catch (HibernateException e) {
log.error(e);
throw SessionFactoryUtils.convertHibernateAccessException(e);
}
if (list.size() != 1) {
log.debug("getRandomAdmin didn't find any user");
return 0;
}
log.debug("found: " + list.get(0));
return list.get(0).longValue();
}
答案 0 :(得分:2)
查看此链接: http://www.shredzone.de/cilla/page/53/how-to-fetch-a-random-entry-with-hibernate.html
Criterion restriction = yourRestrictions;
Object result = null; // will later contain a random entity
Criteria crit = session.createCriteria(Picture.class);
crit.add(restriction);
crit.setProjection(Projections.rowCount());
int count = ((Number) crit.uniqueResult()).intValue();
if (0 != count) {
int index = new Random().nextInt(count);
crit = session.createCriteria(Picture.class);
crit.add(restriction);
result = crit.setFirstResult(index).setMaxResults(1).uniqueResult();
}
这就是你想要的。将Hibernate保持为抽象层,同时仍然能够查询随机对象。但是性能有点受损。
虽然我一直在使用Hibernate,但我不知道一种易于使用的更优雅的方式。 Imho你应该把这个方法包在幕墙后面。
答案 1 :(得分:1)
由于不赞成使用所接受答案中的条件,因此我想出了如何使用CriteriaBuilder和CriteriaQuery进行操作,并且只想在此处共享。我使用here描述的模式通过自定义方法扩展了我的存储库:
@Repository
public class UserRepositoryCustomImpl implements UserRepositoryCustom {
@Autowired
EntityManager em;
public User findRandomUserInCountry(String countryCode) throws NotFoundException {
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Long> cqCount = qb.createQuery(Long.class);
Root<User> userCountRoot = cqCount.from(User.class);
cqCount.select(qb.count(userCountRoot)).where(qb.equal(userCountRoot.get("countryCode"), countryCode));
int count = em.createQuery(cqCount).getSingleResult().intValue();
System.out.println("Count of users: " + count);
if (0 != count) {
int index = new Random().nextInt(count);
CriteriaQuery<User> cqUser = qb.createQuery(User.class);
Root<User> userRoot = cqUser.from(User.class);
cqUser.select(userRoot).where(qb.equal(userRoot.get("countryCode"), countryCode));
User randomUser = em.createQuery(cqUser).setFirstResult(index).setMaxResults(1)
.getSingleResult();
System.out.println("Random user: " + randomUser.getName());
return randomUser;
} else {
throw new NotFoundException("No users available in repository for country: " + countryCode);
}
}
}