Как загрузить несколько спящих объектов в порядке ПК
Как мы загружаем сущности, используя 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
, Theids
параметр будет передавать идентификаторы сущностей в том же порядке, в котором они были определены в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())));