【Kotlin】SpringBoot/JPAのはじめ方1 - Entity編

こんにちは。こまつです。


はじめに
---
KotlinでSpringBoot/JPAをはじめる人向けの記事です。
何回かに分けてHelloSpringBoot的なアプリを作っていきます。

今回はプロジェクト構築からEntity定義・jpaによるテーブル作成まで。
サンプルはKotlinですがJavaもほとんど一緒です。


プロジェクトを作成する
---
イニシャライザーで作成しましょう。
https://spring.pleiades.io/quickstart
(intellijを使うと楽です)

◾️設定値
Language：kotlin       <- ここではkotlin
Type: gradle          <- ここではgradle
Packaging: jar        <- tomcatを含んだjarになります
dependencies: SpringWeb, SpringDataJPA, MySQL Driver  <- これを選択

プロジェクトが作成されたらこんな感じになります。
![スクリーンショット 2022-09-20 0.26.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1342736/e9b80d65-a886-611c-11fb-53d2092ce17f.png)



パッケージを切る
---
私はこのようなパッケージ構成にすることが多いですが何でもいいです。
UtilとかConstはあまり使わないので、どうしても必要になったら直下に置いてます。

```
com
  └─example
      └─hellospringbootkt
         ├─controllers  <- リクエストを受けるクラス
         ├─entities     <- テーブルを表現したクラス
         ├─exceptions   <- 自作の例外クラス
         ├─repositories <- DB操作用のクラス/IF
         └─services     <- サービス/ビジネスクラス
```

Entityを定義する
---
これがアーキテクチャの真ん中なので一番先に作ります。
DBテーブルと1:1になるクラスでテーブルデータを保持します。

```User.kt
// ユーザを表現する       <- このクラスは特に重要なので必ずコメントを入れる
@Entity                <- Entityであるという目印(必須)
@Table(name = "users") <- テーブル名を設定する(intellijなら存在しないテーブルでwarnが出る)
data class User(       <- kotlinならデータクラスにする
    // ユーザID         <- このクラスのコメントは必ず入れる
    @Id                <- IDカラム
    @GeneratedValue(strategy = GenerationType.IDENTITY) <- インクリメントしたいカラムに付ける
    val id: Int?,      <- nullで登録するとインクリメントしたIDが設定される
    // ユーザ名
    @Column(length = 100, nullable = false) <- カラム長、null可否を設定する
    val name: String
) : Serializable

```

リポジトリを定義する
---
EntityをDBから取得、登録、更新、削除するクラスです。
こういうもんだと思って脳死で作成します。

```UserRepository.kt
@Repository   <- Repositoryであることを明示
interface UserRepository : JpaRepository<User, Int> { <- 主キーの型を指定
}
```

設定ファイルに設定値を書く
---
設定項目は多いのでプロジェクトを進めながら育てて行くのがいいと思います。
とりあえず以下設定がされていればしばらくは困らないと思います。

```application.yml
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=utf8 <- DB接続文字列
    username: root                               <- DB接続ユーザ
    password: xxxxxxx                            <- DB接続パスワード
    driver-class-name: com.mysql.cj.jdbc.Driver  <- ドライバの種類
  jpa:
    database: mysql                      <- DBの種類
    hibernate:
      ddl-auto: create                   <- entityからテーブルを作成するか。local以外はしないので基本はnone
  jackson:
    property-naming-strategy: SNAKE_CASE <- request, responseのJSONをsnakeにする

logging:
  level:
    org:
      hibernate:
        sql: debug                       <- SQLを出力する(本番では外す)
        type:
          descriptor:
            sql:
              BasicBinder: trace         <- SQLパラメータを出力する
          EnumType: trace                <- SQLパラメータ(enum)を出力する
```


アプリケーションを起動する
---
起動できたらEntityを元にテーブルが生成されています。
※ application.ymlにddl-auto: create, update等が必要
※ Repositoryは作成しなくてもTableは作られます。
![スクリーンショット 2022-09-24 23.54.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1342736/a2cdeb86-656b-dcdc-f4b4-d4e6e3bd2710.png)


まとめ
---
◾️Entityはテーブルデータを入れるためのクラス
◾️RepositoryはEntityをDBから取得、登録、更新、削除するクラス(IF)
◾️JPAにはentityからtableを作成する機能がある。
メリット：
・かならずEntityとテーブルの形(カラム名)が揃う
・Entityの変更にテーブルが追従する
デメリット
・カラム順序が指定できないので結局テーブルの手直しが必要
・本番環境ではテーブルを勝手に変更されたくないので必ずoffにしておく必要がある
・テーブルが増えてくるとER図が必要になってくる(Entityだけでは関連が俯瞰できない)
※基本的には小規模アプリや、初回DDL作成のための機能と割り切った方がいい