LoginSignup
9
4

More than 5 years have passed since last update.

Kotlin: org.jetbrains.exposed.sql で日付型をINSERTするときにちょっとはまった話

Last updated at Posted at 2017-08-25

Kotlin初心者が Exposed を使ってMySQLに日付型をINSERTするときにしばらくはまったのでメモしておきます。

はまった経緯

こんな感じのテーブルをつくりまして、

create table app_test_logs (
  id integer auto_increment primary key,
  log_datetime datetime not null,
  ops_id int not null,
  created_at datetime not null,
  updated_at datetime not null
);

Ktではこんなオブジェクトを書きまして、

object AppTestLogs : Table("app_test_logs") {
    val id = integer("id").autoIncrement().primaryKey()
    val logDatetime = datetime("log_datetime")
    val opsId = integer("ops_id")
    val createdAt = datetime("created_at")
    val updatedAt = datetime("updated_at")
}

実際にこんな感じで登録してみようとしたときに、

AppTestLogs.insert {
   val cal = Calendar.getInstance()
   cal.set(Calendar.YEAR, 2017)
   cal.set(Calendar.MONTH, 8 -1)
   cal.set(Calendar.DAY_OF_MONTH, 25)
   cal.set(Calendar.HOUR_OF_DAY, 12)
   cal.set(Calendar.MINUTE, 11)
   cal.set(Calendar.SECOND, 15)

   it[logDatetime] = cal.time // <- エラーになる
   it[opsId] = 1
}

InteliJさんがいうには、Column / DateTime にそんなものはいらないぞ、と言われているようでした。

試行錯誤

ならば、これでどうか。

it[logDatetime] = java.util.Date(cal.timeInMillis) // <- エラー :(

じゃあこんどこそ!

it[logDatetime] = java.sql.Date(cal.timeInMillis) // <- エラー :(

あれー?

いろいろぐぐってみたのですが、はまっている人がいないようだったのでじゃあソース見てみるかと。

import org.joda.time.DateTime

あ、このひとInteliJさんもサジェストしてた。

import org.joda.time.DateTime

...

it[logDatetime] = DateTime(cal.timeInMillis) // 通った!!!

    override fun notNullValueToDB(value: Any): Any {
        if (value is DateTime) {
            val millis = value.millis
            if (time) {
                return java.sql.Timestamp(millis)
            }
            else {
                return java.sql.Date(millis)
            }
        }
        return value
    }

この辺ですかね。

こっちみると、java.sql.Date / java.sql.Timestamp もごにょごにょしてるので、なんか入れてくれても良さそうなのに。

とりあえず、Exposedライブラリの日付型使うときは、 org.joda.time.DateTime 使うと良さそうというお話でした。

コードサンプル

だいたいこんな感じです。

import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.transaction
import org.joda.time.DateTime

object AppTestLogs : Table("app_test_logs") {
  val id = integer("id").autoIncrement().primaryKey()
  val logDatetime = datetime("log_datetime")
  val opsId = integer("ops_id")
  val createdAt = datetime("created_at")
  val updatedAt = datetime("updated_at")
}

fun main(args: Array<String>) {
  loadLogData()
}

fun loadLogData () {
  Database.connect("jdbc:mysql://localhost/mydb", "com.mysql.jdbc.Driver","myuser","password")
  transaction {
    AppTestLogs.insert {
      val cal = Calendar.getInstance()
      cal.set(Calendar.YEAR, 2017)
      cal.set(Calendar.MONTH, 8 -1)
      cal.set(Calendar.DAY_OF_MONTH, 25)
      cal.set(Calendar.HOUR_OF_DAY, 12)
      cal.set(Calendar.MINUTE, 11)
      cal.set(Calendar.SECOND, 15)

      it[logDatetime] = DateTime(cal.timeInMillis)
      it[opsId] = 1
      val currentTime = DateTime(Calendar.getInstance().timeInMillis)
      it[createdAt] = DateTime(currentTime)
      it[updatedAt] = DateTime(currentTime)
    }
  }
}
9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4