こんにちは、白々さじきです。
今回は、前回使った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点です。
- importの追加
@Table
アノテーションを追加- DBとテーブルを関連付け
@Id
アノテーションをid
に追加- プライマリキーを指定
- デフォルトの
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を使用する方法よりかなり簡単でしたね!
次は、他のメソッドを作成してみようと思います。
この記事が誰かの役に立てれば幸いです。
サポートのお願い
下記リンクからお買い物いただけると、ブログ運営のための費用が増え、有料サービスを利用した記事作成が可能になります。ご協力よろしくお願いします!

コメント