Как загрузить несколько спящих объектов в порядке ПК

Как мы загружаем сущности, используя hibernate в порядке списка Pks, который предоставляется для запроса hibernate. В приведенном ниже коде порядок вывода списка находится в порядке возрастания, а не в порядке, в котором Pks предоставляется в аргументе

Criteria criteria = s.createCriteria(entityClass).add(Restrictions.in(idPropertyName, pks));

List list = criteria.list();

1 ответ

Как я объяснил в этой статье, есть несколько способов достичь этой цели.

В вашем примере вы использовали устаревшие критерии Hibernate, но поскольку они устарели с Hibernate 4 и, вероятно, будут удалены в Hibernate 6.

Поэтому лучше использовать одну из следующих альтернатив.

Обратите внимание, что в вашем примере значения идентификатора объекта определены в pks переменная List type, и я собираюсь повторно использовать его в примерах ниже.

JPQL

Вы можете использовать запрос JPQL, подобный следующему:

List<Book> books = entityManager
.createQuery(
    "select b " +
    "from Book b " +
    "where b.id in (:ids)", Book.class)
.setParameter("ids", pks)
.getResultList();

При использовании JPQL ids параметр будет передавать идентификаторы сущностей в том же порядке, в котором они были определены в pks переменная.

API критериев

Если вы хотите построить запрос динамически, вы можете использовать запрос Criteria API:

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Book> query = builder.createQuery(Book.class);

ParameterExpression<List> ids = builder.parameter(List.class);

Root<Book> root = query
.from(Book.class);

query
.where(
    root.get("id").in(
        ids
    )
);

List<Book> books = entityManager
.createQuery(query)
.setParameter(ids, pks)
.getResultList();

При использовании Criteria API ids параметр будет передавать идентификаторы сущностей в том же порядке, в котором они были определены в pks переменная.

MultiLoad, специфичный для гибернации

List<Book> books = entityManager
.unwrap(Session.class)
.byMultipleIds(Book.class)
.multiLoad(pks);

По умолчанию Hibernate multiLoad, The ids параметр будет передавать идентификаторы сущностей в том же порядке, в котором они были определены в pksпеременная. Только если ты позвонилenableOrderedReturn(false) явно, то набор результатов не будет упорядочен.

Теперь JPQL и Criteria API могут извлечь выгоду из hibernate.query.in_clause_parameter_paddingоптимизация, что позволяет увеличить механизм кэширования SQL-операторов.

Для получения дополнительных сведений о загрузке нескольких объектов по их идентификатору ознакомьтесь с этой статьей.

Вы получаете их, а затем сортируете их с помощью компаратора, который сравнивает индекс каждой сущности в списке.

Например:

Map<Long, Integer> indexById = new HashMap<>();
for (int i = 0; i < pks.size(); i++) {
    indexById.put(pks.get(i), i);
}

List<MyEntity> entities = seachByIds(pks);

entities.sort(Comparator.comparing(entity -> indexById.get(entity.getId())));
Другие вопросы по тегам