我们如何使用hibernate按照提供给hibernate查询的Pks列表的顺序加载实体。 在下面的代码中,列表输出的顺序是升序而不是参数中提供Pks的顺序
Criteria criteria = s.createCriteria(entityClass).add(Restrictions.in(idPropertyName, pks));
List list = criteria.list();
答案 0 :(得分:0)
你得到它们,然后使用比较器对它们进行排序,比较器列出了每个实体的索引。
例如:
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())));
答案 1 :(得分:0)
正如我在this article中解释的那样,有几种方法可以实现这一目标。
在您的示例中,您使用的是旧版Hibernate Criteria,但由于自Hibernate 4起已不推荐使用,因此很可能在Hibernate 6中将其删除。
因此,最好使用以下替代方法之一。
请注意,在您的示例中,您具有在pks
类型的List
变量中定义的实体标识符值,我还将在以下示例中重复使用它。 / p>
您可以使用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
变量中定义的顺序传递实体标识符。
如果要动态构建查询,则可以使用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
变量中定义的顺序传递实体标识符。
List<Book> books = entityManager
.unwrap(Session.class)
.byMultipleIds(Book.class)
.multiLoad(pks);
默认情况下,休眠
multiLoad
,ids
参数将按照在pks
变量中定义的顺序传递实体标识符。仅当您显式调用enableOrderedReturn(false)
时,结果集才会被排序。
现在,JPQL和Criteria API也可以从hibernate.query.in_clause_parameter_padding
optimization中受益,这使您可以增强SQL语句缓存机制。
有关通过其标识符加载多个实体的更多详细信息,请查看this article。