永続化エンティティ

CrudRepository.save(…) メソッドを使用して、集約を保存できます。集約が新しい場合、集約ルートの挿入が発生し、その後に直接または間接的に参照されるすべてのエンティティの挿入ステートメントが続きます。

集約ルートが新規ではない場合、すべての参照エンティティが削除され、集約ルートが更新され、すべての参照エンティティが再度挿入されます。インスタンスが新しいかどうかは、インスタンスの状態の一部であることに注意してください。

このアプローチには、明らかな欠点がいくつかあります。参照されたエンティティのうち実際に変更されたものがわずかしかない場合、削除と挿入は無駄です。このプロセスは改善される可能性があり、おそらく改善される予定ですが、Spring Data JDBC が提供できるものには特定の制限があります。集約の以前の状態はわかりません。そのため、更新プロセスは常にデータベースで見つかったものをすべて取得し、save メソッドに渡されたエンティティの状態に変換する必要があります。

詳細については、エンティティ状態の検出も参照してください。

集約のロード

Spring Data JDBC は、集約をロードする方法を 2 つ提供します。

  1. 従来のバージョン 3.2 より前のバージョンの唯一の方法は非常に簡単です。クエリが CrudRepository メソッド、派生クエリ、アノテーション付きクエリに基づいている場合、各クエリは独立して集約ルートをロードします。集約ルートが他のエンティティを参照する場合、別のステートメントでロードされます。

  2. Spring Data JDBC 3.2 では、単一クエリのロードを使用できます。これにより、単一の SQL クエリで任意の数の集約を完全にロードできます。これは、特に多くのエンティティで構成される複雑な集約の場合、大幅に効率的になるはずです。

    現在、単一クエリの読み込みはさまざまな方法で制限されています。

    1. 集約にはネストされたコレクションがあってはなりません。これには Map が含まれます。将来的にはこの制約を取り除く予定です。

    2. 集約では、AggregateReference または埋め込みエンティティを使用してはなりません。将来的にはこの制約を取り除く予定です。

    3. データベース言語はそれをサポートする必要があります。Spring Data JDBC が提供するダイアレクトのうち、H2 と HSQL を除くすべてがこれをサポートしています。H2 と HSQL は分析関数 (別名ウィンドウ関数) をサポートしていません。

    4. これは CrudRepository の find メソッドに対してのみ機能し、派生クエリやアノテーション付きクエリに対しては機能しません。将来的にはこの制約を取り除く予定です。

    5. 単一クエリの読み込みは、setSingleQueryLoadingEnabled(true) を呼び出して、JdbcMappingContext で有効にする必要があります。

いずれかの条件が満たされない場合、Spring Data JDBC は集約をロードするデフォルトのアプローチに戻ります。

単一クエリの読み込みは実験的であると考えられます。それがどのように機能するかについてのフィードバックをお待ちしております。
シングルクエリロードは SQL と略すこともできますが、構造化クエリ言語との混同がほぼ確実であるため、そうすることは強くお勧めしません。

ID 生成

Spring Data は、識別子プロパティを使用してエンティティを識別します。エンティティの ID には、Spring Data の @Id (Javadoc) アノテーションを付ける必要があります。

データベースに ID 列の自動インクリメント列がある場合、生成された値は、データベースに挿入された後にエンティティに設定されます。

Spring Data は、エンティティが新しく、識別子の値がデフォルトで初期値になっている場合、識別子の列の値を挿入しようとはしません。これは、プリミティブ型の場合は 0 であり、識別子プロパティが Long などの数値ラッパー型を使用している場合は null です。

エンティティ状態の検出では、エンティティが新しいかどうか、データベースに存在すると予想されるかどうかを検出する戦略について詳しく説明します。

重要な制約の 1 つは、エンティティを保存した後、そのエンティティが新しいものであってはならないことです。エンティティが新しいかどうかは、エンティティの状態の一部であることに注意してください。自動インクリメント列では、ID 列の値を使用して Spring Data によって ID が設定されるため、これは自動的に行われます。

テンプレート API

リポジトリの代替として、Spring Data JDBC は、リレーショナルデータベースにエンティティをロードして永続化するためのより直接的な手段として JdbcAggregateTemplate (Javadoc) を提供します。リポジトリは、主に JdbcAggregateTemplate を使用して機能を実装します。

このセクションでは、JdbcAggregateTemplate の最も興味深い部分のみを取り上げます。より完全な概要については、JdbcAggregateTemplate の JavaDoc を参照してください。

JdbcAggregateTemplate へのアクセス

JdbcAggregateTemplate は、Spring Bean として使用することを目的としています。アプリケーションを Spring Data JDBC を含めるように設定した場合、任意の Spring Bean で JdbcAggregateTemplate への依存関係を構成することができ、Spring Framework は適切に構成されたインスタンスを挿入します。

これには、Spring Data リポジトリのカスタムメソッドを実装するために使用するフラグメントが含まれており、これにより、JdbcAggregateTemplate を使用してリポジトリをカスタマイズおよび拡張できるようになります。

持続する

JdbcAggregateTemplate は、エンティティを永続化するための 3 種類のメソッド ( saveinsertupdate) を提供します。それぞれに 2 つの種類があります。単一の集約を操作するもの (上記とまったく同じ名前) と、Iterable に対する All サフィックス操作です。

save は、リポジトリ内の同じ名前のメソッドと同じことを行います。

insert と update は、エンティティが新規の場合はテストをスキップし、名前で示されるように新規または既存の集約であると想定します。

クエリ

JdbcAggregateTemplate は、集約をクエリしたり、集約のコレクションについてクエリを実行したりするための、さまざまなメソッドを提供します。特別な注意が必要なメソッドが 1 つあります。それは、Query を引数として受け取るメソッドです。これらのメソッドを使用すると、次のようにプログラムで構築されたクエリを実行できます。

template.findOne(query(where("name").is("Gandalf")), Person.class);

query メソッドによって返される Query (Javadoc) は、選択する列のリスト、where 句 (CriteriaDefinition 経由)、および limit 句と offset 句の指定を定義します。Query クラスの詳細については、JavaDoc を参照してください。

where が静的メンバーである Criteria (Javadoc) クラスは、クエリの where 句を表す org.springframework.data.relational.core.query.CriteriaDefinition[] の実装を提供します。

Criteria クラスのメソッド

Criteria クラスは次のメソッドを提供します。これらのメソッドはすべて SQL 演算子に対応しています。

  • Criteria and (String column): 指定された property を持つ連鎖 Criteria を現在の Criteria に追加し、新しく作成された Criteria を返します。

  • Criteria or (String column): 指定された property を持つ連鎖 Criteria を現在の Criteria に追加し、新しく作成された Criteria を返します。

  • Criteria greaterThan (Object o)> 演算子を使用して基準を作成します。

  • Criteria greaterThanOrEquals (Object o)>= 演算子を使用して基準を作成します。

  • Criteria in (Object…​ o): varargs 引数に IN 演算子を使用して、基準を作成します。

  • Criteria in (Collection<?> collection): コレクションを使用して IN 演算子を使用して、基準を作成します。

  • Criteria is (Object o): 列マッチング(property = value)を使用して基準を作成します。

  • Criteria isNull ()IS NULL 演算子を使用して基準を作成します。

  • Criteria isNotNull ()IS NOT NULL 演算子を使用して基準を作成します。

  • Criteria lessThan (Object o)< 演算子を使用して基準を作成します。

  • Criteria lessThanOrEquals (Object o) 演算子を使用して基準を作成します。

  • Criteria like (Object o): エスケープ文字処理なしで LIKE 演算子を使用して基準を作成します。

  • Criteria not (Object o)!= 演算子を使用して基準を作成します。

  • Criteria notIn (Object…​ o): varargs 引数に NOT IN 演算子を使用して、基準を作成します。

  • Criteria notIn (Collection<?> collection): コレクションを使用して NOT IN 演算子を使用して、基準を作成します。

楽観的ロック

Spring Data は、集約ルート上で @Version (Javadoc) のアノテーションが付けられた数値属性を使用してオプティミスティックロックをサポートします。Spring Data がそのようなバージョン属性を持つ集約を保存するときは常に、次の 2 つのことが起こります。

  • 集約ルートの更新ステートメントには、データベースに格納されているバージョンが実際に変更されていないことを確認する where 句が含まれます。

  • そうでない場合は、OptimisticLockingFailureException がスローされます。

また、エンティティとデータベースの両方でバージョン属性が増加するため、同時アクションは変更を認識し、上記で説明したように該当する場合は OptimisticLockingFailureException をスローします。

このプロセスは、新しい集合体の挿入にも適用されます。null または 0 バージョンは新しいインスタンスを示し、その後、増加したインスタンスはインスタンスを新規ではないものとしてマークします。UUID が使用されます。

削除中にバージョンチェックも適用されますが、バージョンは増加しません。