Как получить список из 10 случайных уникальных объектов с Hibernate? - PullRequest
6 голосов
/ 11 декабря 2010

У кого-нибудь есть HQL-запрос о том, как получить список из 10 случайных уникальных объектов из базы данных?

Это должно быть сделано в базе данных, а не в приложении. Я хотел бы получить что-то, что имеет лучшую производительность, чем мое текущее решение, которое в значительной степени делает 10 запросов на заполнение списка.

Ответы [ 3 ]

10 голосов
/ 12 декабря 2010

HQL будет выглядеть примерно так:

session.createQuery("select o from Object o order by rand()")
   .setMaxResults(10)
   .list()

Функция rand () передается в базу данных, поэтому замените ее любой функцией, которую использует ваша база данных.

5 голосов
/ 11 декабря 2010

Я ни в коем случае не эксперт по HQL, но в SQL вы могли бы сделать это с

select ... order by RANDOM() limit 10

Так что, немного погуглив, я понял, как сделать предельный бит и случайный бит .

0 голосов
/ 12 декабря 2010

Пожалуйста, не стесняйтесь комментировать и публиковать улучшения. Вот что я получил:

public List<Item> getRandomTenItems() {

    DetachedCriteria criteria = DetachedCriteria.forClass(Item.class).addOrder(Order.desc("id"));
    List<Item> idlist = new LinkedList<Item>(getHibernateTemplate().findByCriteria(criteria, 0, 1));
    long max =  idlist.get(0).getId();

    criteria = DetachedCriteria.forClass(Item.class).addOrder(Order.asc("id"));
    idlist = new LinkedList<Item>(getHibernateTemplate().findByCriteria(criteria, 0, 1));
    long min =  idlist.get(0).getId();

    List<Item> rtn = new LinkedList<Item>();
    HashSet<Long> ids = new HashSet<Long>();
    int i=0;
    while(i<10) {
        long itemId = RandomUtils.rand(min, max);
        if(ids.contains(itemId)) continue;
        List<Item> list = new LinkedList<Item>(getHibernateTemplate().findByNamedParam(
                "from Item where archived = false and available = true and id = :itemId", "itemId", itemId));
         if(!list.isEmpty()){
            rtn.add(list.get(0));
            ids.add(list.get(0).getId());
            i++;
         }
    }
    return rtn;
}
...