1. 概要

この記事では、JPAを使用してを並べ替えるさまざまな方法について説明します。

2. JPA /JQLAPIを使用した並べ替え

JQLを使用した並べ替えは、 OrderBy句を使用して行われます。

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 rderby句に追加されます。

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クエリ文字列の NULLSFIRSTまたはNULLSLAST句を使用してカスタマイズできます。

簡単な例を次に示します。Foonameで降順で並べ替え、最後にNullを配置します。

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

生成されるSQLクエリには、 is 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. 1対多の関係の並べ替え

基本的な例を超えて、エンティティを1対多の関係Barに並べ替えるFooエンティティのコレクションを含むユースケースを見てみましょう。

BarエンティティとそれらのFooエンティティのコレクションを並べ替えたい–JPAはこのタスクにとって特に簡単です。

  1. コレクションの並べ替え:BarエンティティのFooコレクションの前にOrderByアノテーションを追加します。
    @OrderBy("name ASC")
    List <Foo> fooList;
  2. コレクションを含むエンティティの並べ替え:
    String jql = "Select b from Bar as b order by b.id";
    Query barQuery = entityManager.createQuery(jql);
    List<Bar> barList = barQuery.getResultList();

@OrderBy アノテーションはオプションですが、この場合は、各BarFooコレクションを並べ替えるために使用しています。

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

最初のクエリは、parent Barエンティティを並べ替えます。 2番目のクエリは、Barに属する子Fooエンティティのコレクションを並べ替えるために生成されます。

3. JPA基準クエリオブジェクトAPIを使用した並べ替え

JPA基準の場合– 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")));

ge tメソッドの引数は、属性の名前と一致する必要があるため、大文字と小文字が区別されます。

単純なJQLとは対照的に、JPA Criteria Query Object API は、クエリで明示的な順序方向を強制します。 このコードスニペットの最後の行で、 criteriaBuilder オブジェクトが、 asc メソッドを呼び出すことにより、昇順の並べ替え順序を指定していることに注意してください。

上記のコードを実行すると、JPAは以下に示すSQLクエリを生成します。 JPA Criteria Objectは、explicit 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メソッドに渡すだけです。

簡単な例を次に示します。nameidで、それぞれascdescの順序で並べ替えます。

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

4. 結論

この記事では、Java Persistence APIの並べ替えの選択肢について、単純なエンティティと1対多の関係にあるエンティティについて説明します。 これらのアプローチは、ソート作業の負担をデータベース層に委任します。

このJPAソーティングチュートリアルの実装は、 GitHubプロジェクトにあります。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。