DEV Community

kaede
kaede

Posted on

Kotlin Springboot -- Part 22 JPA で Postgres DB とつなぐ

JPA の依存性の確認。

まず親のモジュールにいれる。

現状、親の gradle の依存ファイルは

plugins {
    id("org.springframework.boot") version "2.7.2"
    id("io.spring.dependency-management") version "1.0.12.RELEASE"
    kotlin("jvm") version "1.6.21"
    kotlin("plugin.spring") version "1.6.21"
    kotlin("plugin.jpa") version "1.6.21"
    kotlin("plugin.allopen") version "1.6.21"
}
Enter fullscreen mode Exit fullscreen mode

既に JPA のプラグイン入っており

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation ("com.google.code.gson:gson:2.9.1")
    runtimeOnly("com.h2database:h2")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
    testImplementation("org.amshove.kluent:kluent:1.68")
Enter fullscreen mode Exit fullscreen mode
  • spring boot starter jpa
  • reflect
  • stdlib-jdk8

公式で必要とされるこれらがはいっていた。

https://www.javadrive.jp/start/install/index5.html#section4

記事では jdk を使えと書いてあった。
しかし、jdk は jre を含むので大丈夫。

これに依存性として postgres を追加

https://github.com/DioPires/kotlin-spring-postgres-example/blob/master/build.gradle.kts

    runtimeOnly("org.postgresql:postgresql")
Enter fullscreen mode Exit fullscreen mode

また、postgres を追加


postgres DB サーバーの作成とテーブルの生成

https://dev.to/kaede_io/sql-ji-chu-part-04-docker-compose-deli-tetakontenade-db-sabali-tishang-geshi-niteburuwozuo-ru-3ia5

docker-compose で作った

person テーブルで name と age のみ。
これだと SQL ではエラーを出さない。
しかしフレームワークでエラーを出すので後ほど ID をいれた。


postgres の読み込み先を追加

https://intellectual-curiosity.tokyo/2019/04/21/spring-boot%E3%81%A7%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/#applicationproperties

同様にこのサイトを参考にして

application.properties というファイルを作成

spring.datasource.url=jdbc:postgresq//localhost:5444/person
spring.datasource.username=kaede
spring.datasource.password=pass
spring.jpa.generate-ddl=true
Enter fullscreen mode Exit fullscreen mode

https ではなく、jbdc で URL を書き、DB 名を書く
localhost:5444/person
に今回はなる。ポート指定がないと 5432 になるようだ。

ルートユーザーとパスを書く


Driver に JPA と Postgres の依存を追加

Root 同様、Driver の build.gradle.kts にも JPA の dependencies を入れる。

dependencies {
// ...
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    runtimeOnly("org.postgresql:postgresql")
}
Enter fullscreen mode Exit fullscreen mode

spring...jpa と postgres をいれた。


PersonTableEntity.kt を作成

既存の PersonEntity.kt というファイルがあるので
かぶりを避けるために PersonTableEntity.kt にした。

package com.kaede

import javax.persistence.*

@Entity
@Table(name="person")
data class PersonTableEntity(
    @Id
    @Column(name = "id", nullable = false)
    open val id: Int? = null,
    @Column(name = "name", nullable = false)
    open val name: String? = null,
    @Column(name = "age", nullable = false)
    open val age: Int? = null
)
Enter fullscreen mode Exit fullscreen mode

persistence でここのアノテーションを使えるようにする。
ID がないとエラーになる。
なので DB にも追加してきた。

最初に無理に null 定義している?ようにみえる。 open val のところはよくわかっていない。


PersonTableDriver.kt を作成

PersonTableEntity と同様の理由で
Table を中に挟んで PersonDriver と別ファイルで作成した。

別のところから取る Driver だから当たり前か。

package com.kaede

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

@Component
interface PersonTableDriver: JpaRepository<PersonTableEntity, Int>
Enter fullscreen mode Exit fullscreen mode

Jpa リポジトリは、エンティティとリンクさせて interface でかく。
すると中の save, saveAll, findAll, などが呼び出せる。

クラスは作らない。


Gateway で呼び出し

@Component
class PersonGateway() : PersonPort { // Port の関数を実装するから
    @Autowired
    lateinit var personDriver: PersonDriver
    @Autowired
    lateinit var personTableDriver: PersonTableDriver
    override fun getAllPersons(): Persons {
        val personTable = personTableDriver.findAll()
        println(personTable);
        val personsEntity = personDriver.findAll()
        val personsDomain= personsEntity.map { personEntity ->
            Person(Name(personEntity.name), Age(personEntity.age))
        }
        return Persons(personsDomain)
    }
Enter fullscreen mode Exit fullscreen mode

既存の Gateway で DI に追加して
findAll を呼び出して print してみた。

PersonApiApplication を実行すると

2022-12-23 02:00:51.601  INFO 3269431
 --- [           main] com.kaede.PersonApiApplicationKt

: Started PersonApiApplicationKt in 2.304 seconds 
(JVM running for 2.682)

[PersonTableEntity(id=1, name=Taro, age=5), 
PersonTableEntity(id=2, name=Hana, age=3)]
Enter fullscreen mode Exit fullscreen mode

このように、DB に入れた中身が引き出せた!!!

Top comments (0)