Kotlin
spring
ORM
exposed

KotlinのORMapper ExposedをSpringから利用

KotlinでSpring(Spring-boot)を使って開発する時、OR Mapperの選択肢はたくさんあります。Java製のOR Mapperがシームレスに使うことができるので、純粋なJavaプログラマは以前使っていたものをそのまま使えます。その一方でKotlinで書かれたORMapperも存在します。Java製ではなくKotlin製のOR Mapperを使う理由はやはり、よりKotlinらしくコードがかけることでしょう。

その一方で、Kotlin製のORMはどれも開発途上であり、決定打にかけるかもしれません。いばらの道を歩みたくなければJava製の実績のあるものを使うのが良いと思います。

さて、Kotlin製のORMの中で僕はExposedを使っています。JetBrains製と言う安心感が主な理由です。また、すべてのコードを終える程度にコンパクトなので、何かあった場合でも自分で対応できるかもしれないことも理由の一つです。

Exposedの使い方自体は、Exposedの使い方がよくまとまっています。
今回はspringから使う場合のまとめです。Springのプロジェクト自体は、Spring Initializerで作成しています。

Gradleの設定

GradleでExposedの依存モジュールを追加します。まずは、Exposed用のrepositoryを追加します。

repositories {
    mavenCentral()
    maven { url('https://dl.bintray.com/kotlin/exposed/') }
}

repositoryを追加したら次はdependenciesを設定します。僕はPostgreSQLを使っているのでドライバーにそれが入っています。

    // https://mvnrepository.com/artifact/org.postgresql/postgresql
    compile group: 'org.postgresql', name: 'postgresql', version: '42.1.4'
    // https://mvnrepository.com/artifact/org.jetbrains.exposed/exposed
    runtime group: 'org.jetbrains.exposed', name: 'exposed', version: '0.8.5'
    // https://mvnrepository.com/artifact/org.jetbrains.exposed/spring-transaction
    compile group: 'org.jetbrains.exposed', name: 'spring-transaction', version: '0.8.5'

transactionの設定

上のdependenciesを見ればわかるように、Exposedは本体の部分と、stringのtransactionをサポートしているモジュールの二つに分かれています。ExposedのSpring Transaction Managerを使用しないと@Transactionalでトランザクションが有効になりません。
とは言え、TransactionManagerの作成でExposedのものを使用するだけです。次のコードを書けばTransactionManagerでExposedのSpringTransactionManagerが使われます。

@Configuration
@EnableTransactionManagement
class TxConfig(val dataSource: DataSource): TransactionManagementConfigurer {
    @Bean
    override fun annotationDrivenTransactionManager(): PlatformTransactionManager = 
        SpringTransactionManager(dataSource)
}

あとは、

@Transactional
@Service
class MyService {
  fun doSomething() {
    // access to db with Exposed
  }
}

とするだけです。

おわり。

おわりに

実際にExposedを使っていると、80%ぐらいは満足できるのですが、やっぱりまだ、機能不足を否めません。データ型もプリミティブなものしかサポートしていません。また、Kotlin自体もよせばいいのに古いJVMもサポートしているため、日付型はorg.joda.time.DateTime型を使っています。新しい言語なのでJava8に限定させちゃえばjava.time.LocalDateTimeなどが使えるのに、もったいないです。

でわでわ