SpringDataJDBCの概要
1. 概要
Spring Data JDBCは、SpringDataJPAほど複雑ではない永続化フレームワークです。 キャッシュ、遅延読み込み、ライトビハインド、またはJPAの他の多くの機能は提供しません。 それでも、独自のORMがあり、マップされたエンティティ、リポジトリ、クエリアノテーション、JdbcTemplateなどのSpring DataJPAで使用されるほとんどの機能を提供します。
覚えておくべき重要なことは、Spring DataJDBCはスキーマ生成を提供しないということです。 その結果、スキーマを明示的に作成する責任があります。
2. SpringDataJDBCをプロジェクトに追加する
Spring Data JDBCは、JDBC依存関係スターターを使用してSpring Bootアプリケーションで使用できます。この依存関係スターターはデータベースドライバーを提供しませんが、。 その決定は開発者が行う必要があります。 Spring DataJPAの依存関係スターターを追加しましょう。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
この例では、H2データベースを使用しています。 先に述べたように、Spring DataJDBCはスキーマ生成を提供しません。 このような場合、スキーマオブジェクトを作成するためのSQLDDLコマンドを含むカスタムschema.sqlファイルを作成できます。 自動的に、Spring Bootはこのファイルを選択し、データベースオブジェクトの作成に使用します。
3. エンティティの追加
他のSpringDataプロジェクトと同様に、アノテーションを使用してPOJOをデータベーステーブルにマップします。 の
Spring Data JPAと同様に、Spring Data JDBCは、デフォルトで、Javaエンティティをリレーショナルデータベーステーブルにマップし、属性を列名にマップする命名戦略を使用します。 デフォルトでは、エンティティと属性のキャメルケース名は、それぞれテーブルと列のスネークケース名にマップされます。 たとえば、 AddressBook という名前のJavaエンティティは、address_bookという名前のデータベーステーブルにマップされます。
また、@Tableおよび@Columnアノテーションを使用して、エンティティと属性をテーブルと列に明示的にマップできます。 たとえば、以下では、この例で使用するエンティティを定義しました。
public class Person {
@Id
private long id;
private String firstName;
private String lastName;
// constructors, getters, setters
}
Personクラスでアノテーション@Tableまたは@Columnを使用する必要はありません。 Spring Data JDBCのデフォルトの命名戦略は、エンティティとテーブルの間のすべてのマッピングを暗黙的に実行します。
4. JDBCリポジトリの宣言
Spring Data JDBCは、SpringDataJPAと同様の構文を使用します。 Repository 、 CrudRepository、またはPagingAndSortingRepository インターフェースを拡張することにより、SpringDataJDBCリポジトリーを作成できます。 CrudRepository を実装することにより、 save 、 delete 、findByIdなどの最も一般的に使用されるメソッドの実装を受け取ります。
この例で使用するJDBCリポジトリを作成しましょう。
@Repository
public interface PersonRepository extends CrudRepository<Person, Long> {
}
ページネーションと並べ替えの機能が必要な場合は、PagingAndSortingRepositoryインターフェイスを拡張するのが最善の選択です。
5. JDBCリポジトリのカスタマイズ
CrudRepository の組み込みメソッドにもかかわらず、特定のケースに対応するメソッドを作成する必要があります。
それでは、 PersonRepository を、変更しないクエリと変更するクエリでカスタマイズしましょう。
@Repository
public interface PersonRepository extends CrudRepository<Person, Long> {
List<Person> findByFirstName(String firstName);
@Modifying
@Query("UPDATE person SET first_name = :name WHERE id = :id")
boolean updateByFirstName(@Param("id") Long id, @Param("name") String name);
}
バージョン2.0以降、SpringDataJDBCはクエリメソッドをサポートしています。 つまり、 findByFirstName、などのキーワードを含むクエリメソッドに名前を付けると、SpringDataJDBCはクエリオブジェクトを自動的に生成します。
ただし、変更クエリでは、 @Modifying アノテーションを使用して、エンティティを変更するクエリメソッドにアノテーションを付けます。 また、@Queryアノテーションで装飾します。
@Query アノテーション内に、SQLコマンドを追加します。 Spring Data JDBCでは、プレーンSQLでクエリを記述します。JPQLのような高レベルのクエリ言語は使用しません。 その結果、アプリケーションはデータベースベンダーと緊密に結合されます。
このため、別のデータベースに変更することも難しくなります。
覚えておく必要があることの1つは、 Spring Data JDBCは、インデックス番号を使用したパラメーターの参照をサポートしていないことです。 パラメータは名前でしか参照できません。
6. データベースへの入力
最後に、上記で作成したSpringDataJDBCリポジトリのテストに役立つデータをデータベースに入力する必要があります。 そこで、ダミーデータを挿入するデータベースシーダーを作成します。 この例では、データベースシーダーの実装を追加しましょう。
@Component
public class DatabaseSeeder {
@Autowired
private JdbcTemplate jdbcTemplate;
public void insertData() {
jdbcTemplate.execute("INSERT INTO Person(first_name,last_name) VALUES('Victor', 'Hugo')");
jdbcTemplate.execute("INSERT INTO Person(first_name,last_name) VALUES('Dante', 'Alighieri')");
jdbcTemplate.execute("INSERT INTO Person(first_name,last_name) VALUES('Stefan', 'Zweig')");
jdbcTemplate.execute("INSERT INTO Person(first_name,last_name) VALUES('Oscar', 'Wilde')");
}
}
上記のように、INSERTステートメントの実行にはSpringJDBCを使用しています。 特に、Spring JDBCはデータベースとの接続を処理し、JdbcTemplateを使用してSQLコマンドを実行できるようにします。 実行されるクエリを完全に制御できるため、このソリューションは非常に柔軟です。
7. 結論
要約すると、Spring Data JDBCは、Spring JDBCを使用するのと同じくらい簡単なソリューションを提供します—その背後に魔法はありません。 それでも、Spring DataJPAの使用に慣れている機能の大部分も提供します。
Spring Data JDBCの最大の利点の1つは、SpringDataJPAと比較してデータベースにアクセスする際のパフォーマンスが向上していることです。 これは、Spring DataJDBCがデータベースと直接通信しているためです。 Spring Dataデータベースをクエリする場合、JDBCにはSpring Dataの魔法のほとんどが含まれていません。
Spring Data JDBCを使用する場合の最大の欠点の1つは、データベースベンダーへの依存です。 データベースをMySQLからOracleに変更することにした場合、異なる方言を持つデータベースから発生する問題に対処する必要があるかもしれません。
このSpringDataJDBCチュートリアルの実装は、GitHubのにあります。