弊社は自社サービスの開発で現在Kotlin言語を利用してSpringBootでのアプリケーション開発を行っています。
なかなか文献が少ない構成ではあるので色々公開していきたいと思ってます。
今回はテーブル定義とdao周りの実装です
前提
言語はkotlin
DBはPostgres
org.jetbrains.exposedの0.38.2を利用。
必要なパッケージ
以下のパッケージをgradleで定義
implementation("org.jetbrains.exposed", "exposed-core", "0.38.2")
implementation("org.jetbrains.exposed", "exposed-dao", "0.38.2")
implementation("org.jetbrains.exposed", "exposed-jdbc", "0.38.2")
implementation("org.jetbrains.exposed", "exposed-jodatime", "0.38.2")
implementation("org.jetbrains.exposed", "exposed-java-time", "0.38.2")
implementation("org.jetbrains.exposed", "exposed-spring-boot-starter", "0.38.2")
implementation("org.jetbrains.exposed", "spring-transaction", "0.38.2")
テーブル定義の実装
import org.jetbrains.exposed.dao.id.IntIdTable
import org.jetbrains.exposed.sql.jodatime.date
import org.jetbrains.exposed.sql.jodatime.datetime
object Users: IntIdTable("users") {
var name = varchar("name", 50)
var address = varchar("address", 255).nullable()
var isActive = bool("is_active").default(false)
var enteredOn = date("entered_on")
var createdAt = datetime("created_at")
}
import org.jetbrains.exposed.dao.id.IntIdTable
object Orders: IntIdTable("orders") {
var user = reference("user_id", Users)
var code = integer("code")
}
org.jetbrains.exposed.sql.Table クラスに定義されているものを利用できます
また、datetimeやdateについては別パッケージとなっているようです
null / not nullの使い分けについてはどの型であっても .nullable()
をつけてあげることで定義可能
リレーション表現については、1:1以上については reference
を利用する形となり、
本記事では触れてませんが、1:0以上については optReference
を利用します
DAOクラスの実装
import org.jetbrains.exposed.dao.IntEntity
import org.jetbrains.exposed.dao.IntEntityClass
import org.jetbrains.exposed.dao.id.EntityID
class User(
id: EntityID<Int>
): IntEntity(id) {
companion object: IntEntityClass<User>(Users)
var name by Users.name
var address by Users.address
var isActive by Users.isActive
var enteredOn by Users.enteredOn
var createdAt by Users.createdAt
}
import org.jetbrains.exposed.dao.IntEntity
import org.jetbrains.exposed.dao.IntEntityClass
import org.jetbrains.exposed.dao.id.EntityID
class Order(
id: EntityID<Int>
): IntEntity(id) {
companion object: IntEntityClass<Order>(Orders)
var user by User referencedOn Orders.user
var code by Orders.code
}
DAO側クラスについては基本的にはテーブルクラスのフィールドを見ているだけになります
リレーション表現については、1:1以上については
reference
を利用する形となり、
本記事では触れてませんが、1:0以上についてはoptReference
を利用します
こちらで触れたリレーション表現の仕方については
referenceは referencedOn
optReferenceは optionalReferencedOn
を利用することになります
最後に
テーブル定義とDAO定義それぞれやらないといけないので若干めんどくさいところもあるんですが、このようにしとくことによって使うときにコードがスリムになり可読性が向上するので是非やっといたほうが良いかなと思います。
また、かんたんなデータ取得はDAO形式、少し凝ったことをやりたくなったらDSLで書くなど逃げ道も用意できるので個人的には嬉しい感じ(もちろんビジネスロジック上で使い分けちゃうと良くないので隠蔽してあげる必要はあると思いますが)
せっかくテーブル定義があるのだから、マイグレーションもやっちゃいたいなと思ってましたが、現在Flyway使ってしまってます。
どうやらExposedでもできるようなので、今度是非試してみたいと思います