Spring Boot + Kotlin でRESTアプリ作成ハンズオン2

前回↓

https://qiita.com/tseno/items/baf9c56b7b3976f5df51

次回↓

https://qiita.com/tseno/items/1b96c1845795232e15ec


# 2.DBの導入

## 2-1. H2 Database Engineを導入する

- build.gradleのdependenciesに以下のようにJPAとH2を追加します。


```groovy:build.gradle（一部）
plugins {
	id 'org.springframework.boot' version '2.7.12'
	id 'io.spring.dependency-management' version '1.0.15.RELEASE'
	id 'org.jetbrains.kotlin.jvm' version '1.6.21'
	id 'org.jetbrains.kotlin.plugin.spring' version '1.6.21'
 	id 'org.jetbrains.kotlin.plugin.jpa' version '1.6.21' // <-- 追加
}
```

```groovy:build.gradle（一部）
dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'com.fasterxml.jackson.module:jackson-module-kotlin'
	implementation 'org.jetbrains.kotlin:kotlin-reflect'
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'		// <-- 追加
	runtimeOnly 'com.h2database:h2'		// <-- 追加
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
```

- 追加したら、gradleをリロードしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/73a007dd-026e-5a5e-5af6-ddcb28a8c582.png)

## 2-2. application.ymlにDBの設定を追加する

- `application.properties` を `application.yml` にリネームします。
- `application.properties` を右クリック → Refactor → Rename → `application.yml`


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/87f58f3d-13b7-e363-e43c-df1115272943.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/1bbd3d9d-a351-1150-487a-3cd8c5b80b87.png)

- `application.yml` に以下の設定を追加します。
- DB_CLOSE_DELAYは、アプリケーション終了時にDBをクローズしないようにするための設定です。
- DB_CLOSE_ON_EXITは、VM終了時にDBをクローズしないようにするための設定です。
- sql.init.data-locationは、初期データ投入SQLファイルを指定します。
- defer-datasource-initializationはDDLをエンティティクラスから自動作成するかどうかです。

```yml:application.yml
spring:
  datasource:
    url: jdbc:h2:mem:tododb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
    driver-class-name: org.h2.Driver
    username: sa
    password:
  sql:
    init:
      encoding: UTF-8
      data-locations: classpath:data.sql
      enabled: true
  h2:
    console:
      enabled: true
  jpa:
    defer-datasource-initialization: true
```


- com.example.demo に エンティティクラス Todo.kt を新規作成します。

```kotlin:Todo.kt
package com.example.demo

import java.time.OffsetDateTime
import javax.persistence.*

@Entity
@Table(name = "todo")
class Todo(

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        var id: Long? = null,

        @Column(name = "title")
        var title: String,

        @Column(name = "description")
        var description: String?,

        @Column(name = "is_completed")
        var isCompleted: Boolean,

        @Column(name = "created_at")
        var createdAt: OffsetDateTime,

        @Column(name = "updated_at")
        var updatedAt: OffsetDateTime
)
```


- `data.sql`を `resources` 配下に作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/8be9ef1a-13ac-3edb-c6c5-14f269c6c65a.png)

- 内容は何でもいいです。

```sql:data.sql
INSERT INTO todo (title, description, is_completed, created_at, updated_at) VALUES
('買い物リスト', '牛乳, パン, りんご', false, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()),
('郵便局に行く', '郵便局で小包を受け取る', false, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()),
('家賃の支払い', '家賃を振り込む', true, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()),
('ジムに行く', '週に2回筋トレ&カーディオ', true, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP()),
('映画を観る', '新作の映画を観に行く', false, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP());

```


- demoアプリケーションを起動して、 http://localhost:8080/h2-console/ を開くとH2コンソールが開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/442ce766-a970-fb14-dcce-371f02f66499.png)






- `SELECT * FROM TODO ` を実行すると、データが入っていることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/142ce29b-4504-e36d-e943-e6e0deb93ef3.png)


## 2-3 GETメソッドの作成

- com.example.demo にリポジトリインタフェースを作成します。
- 継承元のJpaRepositoryはfind、save、delete、existsなど一般的にDB操作に必要なメソッドを一通り持っています。

```kotlin:TodoRepository.kt
package com.example.demo

import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository

@Repository
interface TodoRepository : JpaRepository<Todo, Long>
```


- com.example.demo に controllerクラスを作成します。
- 作成したTodoRepositoryをインジェクションします。

```kotlin:TodoController.kt
package com.example.demo

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController

@RestController
class TodoController(
        val todoRepository: TodoRepository

) {

    @GetMapping("/todos")
    fun getTodos(): List<Todo> {
        return todoRepository.findAll()
    }
}
```


- demoアプリケーションを起動して、 http://localhost:8080/todos にアクセスすると、以下のように出ればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88686/0bcafcd7-c395-2bfe-9e68-302587ba2292.png)

おわり