在循环中一个一个地获取每个实体可能会导致N+1 个查询问题。
因此,一次获取所有实体并在之后进行处理的效率要高得多。
现在,在您提出的解决方案中,您使用的是传统的 Hibernate Criteria,但由于它自 Hibernate 4 以来已被弃用,并且可能会在 Hibernate 6 中被删除,因此最好使用以下替代方案之一。
JPQL
您可以使用如下 JPQL 查询:
List<Song> songs = entityManager
.createQuery(
"select s " +
"from Song s " +
"where s.id in (:ids)", Song.class)
.setParameter("ids", songGroup.getSongIds())
.getResultList();
标准 API
如果要动态构建查询,则可以使用 Criteria API 查询:
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Song> query = builder.createQuery(Song.class);
ParameterExpression<List> ids = builder.parameter(List.class);
Root<Song> root = query
.from(Song.class);
query
.where(
root.get("id").in(
ids
)
);
List<Song> songs = entityManager
.createQuery(query)
.setParameter(ids, songGroup.getSongIds())
.getResultList();
Hibernate 特定的 multiLoad
List<Song> songs = entityManager
.unwrap(Session.class)
.byMultipleIds(Song.class)
.multiLoad(songGroup.getSongIds());
现在,JPQL 和 Criteria API 也可以从hibernate.query.in_clause_parameter_padding
优化中受益,这允许您增加 SQL 语句缓存机制。
有关按标识符加载多个实体的更多详细信息,请查看这篇文章。