【问题标题】:How can I make a sort with filtering using JPA Criteria API?如何使用 JPA Criteria API 进行过滤排序?
【发布时间】:2017-12-29 11:36:51
【问题描述】:

我有以下类描述的实体映射数据库:

@Entity(name = "myitem")
public class MyItem {
   @Id
   private Long id;
   private String type;
}

@Entity(name = "mycontainer")
public class MyContainer {
   @Id
   private Long id;
   @ManyToOne
   private MyItem item;
   ...
}

@Entity(name = "mytable")
public class MyTable {
   @Id
   private Long id;
   @OneToMany
   private Set<MyContainer> containers;
   ...
}

我正在使用 JPA Criteria API 来过滤和排序我的数据。排序和过滤参数动态变化并从 db 中获取结果,我使用 Spring Data JPA Page&lt;S&gt; findAll(Example&lt;S&gt; example, Pageable pageable) (doc)。 它适用于基本排序,但是当我想按某种类型的 MyItem.id 对 MyTable 进行排序时,我遇到了问题。示例:每个容器有 2 个不同类型的项目,我想按只有一种类型的项目 ID 对表进行排序,而忽略第二个值。 甚至可以使用 Spring Data JPA 完成这样的排序吗?

编辑:我在这里需要一种动态方法,因为重要的是我的排序可以通过用户选择的各种字段来完成。

【问题讨论】:

  • 嗨。我正在寻找一些动态排序解决方案,因为在我的系统中排序应该由用户指定的字段完成。在存储库中定义更多方法对我没有帮助。

标签: java spring spring-data spring-data-jpa jpa-criteria


【解决方案1】:

加入实体后,可以使用CriteriaQuery接口的orderBy方法和CriteriaBuilder接口的asc或desc方法定义ORDER BY子句。

cq.orderBy(cb.asc(item.get(MyItem_.id)));

这是一个完整的示例,它将MyTable 与MyContainer 与MyItem 连接起来,并选择由id 的MyItem 的id 排序的MyTable 实体

EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<MyTable> cq = cb.createQuery(MyTable.class);
Root<MyTable> root = cq.from(MyTable.class);
SetJoin<MyTable, MyContainer> containers = root.join(MyTable_.containers);
Join<MyContainer, MyItem> item = containers.join(MyContainer_.item);

cq.orderBy(cb.asc(item.get(MyItem_.id)));

TypedQuery<MyTable> query = em.createQuery(cq);
List<MyTable> tables = query.getResultList();

for (MyTable t : tables) {
    log.info(t);
}

em.getTransaction().commit();
em.close();

所有以_ 结尾的类都是JPA metamodel 类。它们中的每一个都描述了具有相同名称但没有_ 的实体。

【讨论】:

    猜你喜欢
    • 2014-09-01
    • 2018-07-04
    • 1970-01-01
    • 2013-08-25
    • 2018-08-27
    • 2011-07-17
    • 2012-12-19
    • 1970-01-01
    • 2014-11-20
    相关资源
    最近更新 更多