Kotlin × Spring Boot で DBと連携する

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

今回は、Kotlin × Spring Boot を使用してデータベースと連携する方法を紹介します。Spring Boot の JdbcTemplate を活用し、データの取得・保存を実装します。

今回のチュートリアルの参考ページはこちらです。
Spring Boot プロジェクトにデータベースサポートを追加

データベースの追加と設定

JVM アプリケーションでは、データベースとやり取りするために JDBC を使用します。Spring Boot では JdbcTemplate クラス を利用することで、より簡単に DB 操作を実装できます。

今回は JdbcTemplate を使って、データベースとやり取りする MessageService.kt を作成します。

サービス層の作成(MessageService)

Spring Boot では、ビジネスロジックを サービス層(Service Layer) に分けて管理するのが一般的です。この層でデータベースとやり取りするクラスを定義し、Spring の DI(依存性注入) を活用するために @Service アノテーションを付与します。

手順

  1. demo パッケージ内に MessageService.kt を新規作成
  2. 以下のコードを追加
package demo

import org.springframework.stereotype.Service
import org.springframework.jdbc.core.JdbcTemplate
import java.util.*

@Service
class MessageService(private val db: JdbcTemplate) {
    fun findMessages(): List<Message> = db.query("select * from messages") { response, _ ->
        Message(response.getString("id"), response.getString("text"))
    }

    fun save(message: Message): Message {
        db.update(
            "insert into messages values ( ?, ? )",
            message.id, message.text
        )
        return message
    }
}

MessageService.ktのコード解説

コンストラクタ引数と依存性注入

Kotlin では、クラス定義時にコンストラクタを直接指定できます。

class MessageService(private val db: JdbcTemplate)

このように記述することで、Spring Boot の DI 機能 により JdbcTemplate が自動で注入されます。

トレーリングラムダと SAM 変換

findMessages() メソッドでは、db.query() を使用してデータを取得します。

db.query("select * from messages") { response, _ ->
    Message(response.getString("id"), response.getString("text"))
}

この query() メソッドは RowMapper を受け取りますが、Kotlin では SAM(Single Abstract Method)変換 により、ラムダ式で簡単に記述できます。
また、最後の引数がラムダ式の場合、括弧の外に出せる(トレーリングラムダ) ルールを活用しています。

未使用のラムダ引数のアンダースコア(_)

response, index -> ... のように書いた場合、index を使用しないなら _ に置き換えるのが推奨されます。

MessageController クラスのアップデート

先ほど作成した MessageService をコントローラーで呼び出せるように MessageController.kt を修正します。

修正後のコード

package demo

import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.net.URI

@RestController
@RequestMapping("/")
class MessageController(private val service: MessageService) {
    @GetMapping
    fun listMessages() = service.findMessages()

    @PostMapping
    fun post(@RequestBody message: Message): ResponseEntity<Message> {
        val savedMessage = service.save(message)
        return ResponseEntity.created(URI("/${savedMessage.id}")).body(savedMessage)
    }
}

PostMapping とは?

@PostMapping("/") を使用することで、POSTリクエストを受け取って DB にデータを保存する処理 を定義できます。

データベースのスキーマを定義する

  1. schema.sql を作成
    • src/main/resources/ に新規→ファイルを選択し、 schema.sql を作成し、テーブル構造を記述
  2. application.properties に設定を追加
    • src/main/resources/application.properties に設定を記述

1のテーブル構造は下記です。

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

2の設定は下記です。

spring.application.name=demo
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:file:./data/testdb
spring.datasource.username=name
spring.datasource.password=password
spring.sql.init.schema-locations=classpath:schema.sql
spring.sql.init.mode=always

HTTPリクエストのテスト

IntelliJ IDEAでは .http ファイルを使って API を手軽にテストできます。
ただし、IntelliJ IDEA Community 版ではデフォルトで使用できません
なので、HTTPリクエストを実行するプラグインが必要になります。

HTTP リクエストテストを有効化する方法(Apidog Fast Request)

今回はApidog Fast Requestを使ってみようと思います。

  1. IntelliJ IDEA の 「Plugins」 を開く
  2. 「Apidog Fast Request」 を検索しインストール
  3. IDE を再起動

インストール後、HTTP リクエストを直接実行可能 になります!

Apidog Fast Request を使用した API テスト

テストしたい場合は、Apidog Fast Request右側のメニューから選択 し、以下のようにテストしたいエンドポイントを選択してください。

API テスト画面(Apidog Fast Request)

この画面では、定義したエンドポイントを簡単にテストできます。
例えば、POST メソッドを選択し、JSON を送信することでデータの登録が可能になります。

データの登録・取得を実際に試してみる

データを登録(POST)

Apidog Fast Request などを使用して、以下のような JSON を送信します。

{
  "text": "sirajira sajiki"
}

Apidog Fast Requestを使って送ると、下記のようにidが付与されて戻ってきます。

データを取得(GET)

今度は、このデータが取得できているかを確認します。

Apidog Fast Requestを使ってGetしてDB に登録されたデータが正しく取得できれば OK!

まとめ

今回は Spring Boot × Kotlin で DB を操作する方法 を解説しました。
JdbcTemplate を利用することで、シンプルなコードでデータの取得・保存が可能です。

次回は、ID を指定して単体のデータを取得できる API(GET /{id} を実装する方法を解説します。

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

サポートのお願い

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

コメント

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