【问题标题】:How to load multiple Hibernate entities in order of the identifiers or Primary Keys如何按标识符或主键的顺序加载多个 Hibernate 实体
【发布时间】:2016-04-09 11:40:10
【问题描述】:

我们如何使用 Hibernate 按照提供给 Hibernate 查询的 Pks 列表的顺序加载多个实体?

在下面的代码中,列表输出的顺序是升序,而不是在参数中提供 Pks 的顺序

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

List list = criteria.list();

【问题讨论】:

    标签: java hibernate sql-order-by entity identifier


    【解决方案1】:

    你得到它们,然后使用比较器对列表中每个实体的索引进行排序。

    例如:

    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())));
    

    【讨论】:

      【解决方案2】:

      正如我在this article 中解释的那样,有几种方法可以实现这一目标。

      在您的示例中,您使用的是旧版 Hibernate Criteria,但由于它自 Hibernate 4 以来已被弃用,并且可能会在 Hibernate 6 中被删除。

      因此,最好使用以下替代方法之一。

      请注意,在您的示例中,您在List 类型的pks 变量中定义了实体标识符值,我还将在下面的示例中重用它。

      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 变量中定义的相同顺序传递实体标识符。

      Hibernate 特定的 multiLoad

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

      默认情况下,Hibernate multiLoadids 参数将按照它们在 pks 变量中定义的相同顺序传递实体标识符。仅当您显式调用enableOrderedReturn(false) 时,才会对结果集进行排序。

      现在,JPQL 和 Criteria API 也可以从 hibernate.query.in_clause_parameter_padding optimization 中受益,这允许您增加 SQL 语句缓存机制。

      有关按标识符加载多个实体的更多详细信息,请查看this article

      【讨论】:

        猜你喜欢
        • 2013-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多