使用JPA排序


1.概述

本文说明了JPA可用于排序的各种方式。

2.使用JPA / JQL API排序

使用JQL进行排序是在Order By子句的帮助下完成的:

String jql ="Select f from Foo as f order by f.id";
Query query = entityManager.createQuery (jql);

基于此查询,JPA生成以下直接的SQL语句:

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_
    from Foo foo0_ order by foo0_.id

请注意,JQL字符串中的SQL关键字不区分大小写,但实体的名称及其属性是。

2.1。设置排序顺序

默认情况下,排序顺序是升序,但可以在JQL字符串中显式设置。就像在纯SQL中一样,订购选项是asc和desc:

String jql = "Select f from Foo as f order by f.id desc";
Query sortQuery = entityManager.createQuery(jql);

该生成的SQL查询然后将包括顺序方向:

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_
    from Foo foo0_ order by foo0_.id desc

2.2。按多个属性排序

要按多个属性排序,这些属性将添加到JQL字符串的o rder by子句中:

String jql ="Select f from Foo as f order by f.name asc, f.id desc";
Query sortQuery = entityManager.createQuery(jql);

两种排序条件都将出现在生成的SQL查询语句中:

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_
    from Foo foo0_ order by foo0_.name asc, foo0_.id desc

2.3。设置空值的排序优先级

null的默认优先级是特定于数据库的,但可以通过HQL查询字符串中的NULLS FIRST或NULLS LAST子句进行自定义。

下面是一个简单的例子-通过订购名称的符按降序排列,并把空末S:

Query sortQuery = entityManager.createQuery
    ("Select f from Foo as f order by f.name desc NULLS LAST");

生成的SQL查询包括null为1 else 0 end子句(第3行):

Hibernate: select foo0_.id as id1_4_, foo0_.BAR_ID as BAR_ID2_4_,
    foo0_.bar_Id as bar_Id2_4_, foo0_.name as name3_4_,from Foo foo0_ order
    by case when foo0_.name is null then 1 else 0 end, foo0_.name desc

2.4。排序一对多关系

移过基本示例,现在让我们看一个涉及按一对多关系排序实体的用例- 包含Foo实体集合的Bar。

我们想要对Bar实体以及它们的Foo实体集合进行排序- JPA对于此任务特别简单:

1.对集合进行排序:在Bar实体中的Foo集合之前添加OrderBy注释:

@OrderBy("name ASC")
List <Foo> fooList;

2.对集合进行排序:在Bar实体中的Foo集合之前添加OrderBy注释:

String jql = "Select b from Bar as b order by b.id";
Query barQuery = entityManager.createQuery(jql);
List<Bar> barList = barQuery.getResultList();

请注意,@ OrderBy注释是可选的,但我们在这种情况下使用它,因为我们想要对每个Bar的Foo集合进行排序。

让我们看一下发送到RDMS 的SQL查询:

Hibernate: select bar0_.id as id1_0_, bar0_.name as name2_0_ from Bar bar0_ order by bar0_.id

Hibernate:
select foolist0_.BAR_ID as BAR_ID2_0_0_, foolist0_.id as id1_4_0_,
foolist0_.id as id1_4_1_, foolist0_.BAR_ID as BAR_ID2_4_1_,
foolist0_.bar_Id as bar_Id2_4_1_, foolist0_.name as name3_4_1_
from Foo foolist0_
where foolist0_.BAR_ID=? order by foolist0_.name asc

第一个查询对父Bar实体进行排序。生成第二个查询以对属于Bar的子Foo实体的集合进行排序。

3.使用JPA Criteria Query Object API排序

使用JPA Criteria - orderBy方法是设置所有排序参数的“一站式”替代方法:可以设置顺序方向和要排序的属性。以下是方法的API:

  • orderBy( CriteriaBuilder.asc):按升序排序。
  • orderBy( CriteriaBuilder.desc):按降序排序。

每个Order实例都是使用C riteriaBuilder对象通过其asc或desc方法创建的。

下面是一个简单的例子-分拣FOOS通过他们的名字:

CriteriaQuery<Foo> criteriaQuery = criteriaBuilder.createQuery(Foo.class);
Root<Foo> from = criteriaQuery.from(Foo.class);
CriteriaQuery<Foo> select = criteriaQuery.select(from);
criteriaQuery.orderBy(criteriaBuilder.asc(from.get("name")));

get方法的参数区分大小写,因为它需要匹配属性的名称。

与简单的JQL相反,JPA Criteria Query Object API 强制查询中的显式订单方向。请注意,在此代码段的最后一行中,criteriaBuilder对象通过调用其asc方法指定要升序的排序顺序。

执行上面的代码时,JPA会生成如下所示的SQL查询。JPA Criteria Object生成带有显式asc子句的SQL语句:

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_
    from Foo foo0_ order by foo0_.name asc

3.1。按多个属性排序

要按多个属性排序,只需将Order实例传递给orderBy方法,以便对每个要排序的属性进行排序。

这是一个快速示例 - 按名称和ID排序,分别按asc和desc顺序排序:

CriteriaQuery<Foo> criteriaQuery = criteriaBuilder.createQuery(Foo.class);
Root<Foo> from = criteriaQuery.from(Foo.class);
CriteriaQuery<Foo> select = criteriaQuery.select(from);
criteriaQuery.orderBy(criteriaBuilder.asc(from.get("name")),
    criteriaBuilder.desc(from.get("id")));

相应的SQL查询如下所示:

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_
    from Foo foo0_ order by foo0_.name asc, foo0_.id desc