Spring Data CrudRepositoryを使ってDBにアクセスする

こんにちは、白々さじきです。

今回は、前回使ったJdbcTemplateではなく、Spring Data CrudRepositoryを使ってDBからデータを入れたり、データを取得したいと思います。

CrudRepositoryは、Spring Dataが提供するインターフェースで、特定のエンティティに対するCRUD(Create, Read, Update, Delete)操作を簡単に行えます。SQLを直接書かずにデータベースとやり取りできます。

今回は、このチュートリアルを元にやっていきたいと思います。

Messageクラスの更新

まず、Message クラスを CrudRepository に対応するよう変更します。

Messageクラスを下記のように書き換えてください!

import org.springframework.data.annotation.Id
import org.springframework.data.relational.core.mapping.Table

@Table("MESSAGES")
data class Message(val text: String, @Id val id: String? = null)

ここでの修正点は下記の4点です。

  1. importの追加
  2. @Tableアノテーションを追加
    • DBとテーブルを関連付け
  3. @Id アノテーションを id に追加
    • プライマリキーを指定
  4. デフォルトの id null に設定
    • 新しいデータ作成時にIDを自動生成できるためidの指定が不要になる。

CURD操作用のインターフェース

Spring Dataでは、リポジトリのインターフェースを定義するだけで、自動的にCRUD操作が実装されます。SQLを直接書く必要がなく、簡潔にデータベース操作ができます。

なので、このインターフェースの定義を行います。

この時、先ほど宣言したMessage クラスと連携するように CrudRepository のインターフェースを宣言する必要があります。
なので、下記のMessageRepository.kt という名前のファイルを作成し、下記のコードを追加してください。

package com.example.demo

import org.springframework.data.repository.CrudRepository

interface MessageRepository : CrudRepository<Message, String>{
    fun findByText(text: String): List<Message>
}

コードの説明

下記のコードがCrudRepositoryを使うためのインターフェースの宣言です。

interface MessageRepository : CrudRepository<Message, String>

下記のコード部分が、CrudRepositoryでは定義されていないtextから検索するための関数です。

{
    fun findByText(text: String): List<Message>
}

この関数を定義することで、textからでも検索することが可能になります。

MessageServiceの更新

先ほど定義したインターフェースを使うように、MessageServiceの更新を行います。

下記のように修正してください。

package com.example.demo


import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service

@Service
class MessageService(private val db: MessageRepository) {
    fun findMessages(): List<Message> = db.findAll().toList()

    fun findMessageById(id: String): Message? = db.findByIdOrNull(id)

    fun findMessageByText(text: String): List<Message> = db.findByText(text)

    fun save(message: Message): Message = db.save(message)
}

ここで使っているdb.findAll()等のメソッドの説明や他にデフォルトで使うことができるメソッドに関しては、SpringDataのドキュメントに記載があります。

コードの説明

各関数のコードの変更点を説明します。

下記は、データベースに保存されているすべてのMessageオブジェクトを取得します。返り値はIterable型のため、.toList()を使ってList型に変換しています。

db.findAll().toList()

下記は、指定されたIDを持つ型のインスタンスを返すCrudRepository の拡張関数で、idがない時を考慮してくれます。

db.findByIdOrNull(id)

下記は、インターフェースで追加したText型からデータを検索する関数です。Textがない場合は、404で返ってきます。

db.findByText(text)

下記は、データの保存を行うためのメソッドです。新しいデータの場合は INSERT、すでに存在するidのデータの場合は UPDATE になります。

db.save(message)

MessageControllerの更新

getMessageTextを下記のように修正してください。

fun getMessageText(@PathVariable text: String) = service.findMessageByText(text)

前回までは、単体での取得でしたが、複数同じtextがある可能性があるのでList型に変更しました。なので、修正する必要があります。

DBの設定更新

スキーマの設定

DBのスキーマ設定を下記のように変更します。

CREATE TABLE IF NOT EXISTS messages (
    id      VARCHAR(60)  DEFAULT RANDOM_UUID() PRIMARY KEY,
    text    VARCHAR      NOT NULL
);

追加した下記の部分のおかげてデータを追加するたびにidがUUIDで自動生成されます。

DEFAULT RANDOM_UUID()

プロパティの変更

下記のようにプロパティを変更し、新しいDBのtestdb2に保存するように変更します。

spring.datasource.url=jdbc:h2:file:./data/testdb2

HTTPリクエストのテスト

前回同様にApidog Fast Requestを使用してテストを実行し、前回と結果が変わらないかを確認します。

前回同様idの指定なしでTextが保存できました。

また、全体取得、id指定、text指定でも問題なく動作することを確認しました。

前回同様にAPIの実行ができることができました。

まとめ

今回は、Spring Data CrudRepositoryを活用して、データベースとの連携を簡単に行う方法を学びました。

前回のJdbcTemplateを使用する方法よりかなり簡単でしたね!

次は、他のメソッドを作成してみようと思います。

この記事が誰かの役に立てれば幸いです。

サポートのお願い

下記リンクからお買い物いただけると、ブログ運営のための費用が増え、有料サービスを利用した記事作成が可能になります。ご協力よろしくお願いします!

コメント

タイトルとURLをコピーしました