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 JDBCの場合、エンティティには@Idが必要です。 Spring Data JDBCは、 @Id エンティティを識別するための注釈。

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にあります。