Home About Contact
Kotlin , Kotlin Script , SQL

H2 Database Engine を kotlin から使う

H2 Database Engineを kotlin から使う方法を調べた備忘録です。

環境

$ kotlinc -version
info: kotlinc-jvm 1.8.10 (JRE 17.0.8.1+1-Ubuntu-0ubuntu122.04)

データベースに接続 / 後始末

カレントディレクトリに mydb というデータベースを作成して使います。

h2db.main.kts

@file:Repository("https://repo1.maven.org/maven2/")
@file:DependsOn("com.h2database:h2:2.2.222")

import java.io.File
import java.util.UUID
//import java.sql.Connection
//import java.sql.Statement
import org.h2.jdbcx.JdbcConnectionPool

val path = File(".").canonicalPath
val jdbcURI = "jdbc:h2:${path}/mydb"
val connectionPool = JdbcConnectionPool.create(jdbcURI, "", "")
val connection     = connectionPool.getConnection()

// ここにデータベース処理を書く.

connection.close()
connectionPool.dispose()

connectionPool と connection を生成して、それを使ってデータベース処理します。 処理後は close(), dispose() で後始末。

JdbcConnectionPool.create() の第二と第三番目の引数が空文字列になっていますが、必要ならここにユーザー名とパスワードを入れる。
詳細: http://www.h2database.com/javadoc/org/h2/jdbcx/JdbcConnectionPool.html

create

テーブル( note )を作成します。

connection.createStatement().use {
    val cmd = listOf(
        "CREATE TABLE IF NOT EXISTS note (",
        "id BIGINT PRIMARY KEY AUTO_INCREMENT,",
        "uuid LONGVARCHAR NOT NULL,",
        "content LONGVARCHAR NOT NULL)").joinToString("")
    it.execute(cmd)
}

SQL文にパラメータが無い場合は connection.createStatement() を使用する。

insert

行(uuid と content)の挿入。

val uuid0 = UUID.randomUUID().toString()
val content0 = "# Hello, World!"

val insertCmd = "INSERT INTO note(uuid, content) VALUES(?,?)"
connection.prepareStatement(insertCmd).use {
    it.setString(1, uuid0)
    it.setString(2, content0)
    it.executeUpdate()
}

SQL文にパラメータがある場合は connection.prepareStatement() を使用する。

update

uuid を指定して該当する行の内容( content )を更新。

val updateCmd = "UPDATE note SET content=? WHERE uuid=?"
val updateContent  = "# Hello, Again!"
connection.prepareStatement(updateCmd).use {
    it.setString(1, updateContent)
    it.setString(2, uuid0)
    it.executeUpdate()
}

select

存在する行をすべて(ただし最大10件までに制限)標準出力する。

connection.createStatement().use {
    val cmd = "SELECT uuid, content FROM note LIMIT 10"
    val resultSet = it.executeQuery(cmd)
    while (resultSet.next()) {
        val uuid = resultSet.getString("uuid")
        val content = resultSet.getString("content")
        println("- ${content} (${uuid})")
    }
}

uuid を使って指定した行のみを標準出力。

val selectCmd = "SELECT content FROM note WHERE uuid=?"
connection.prepareStatement(selectCmd).use {
    it.setString(1, uuid0)
    val resultSet = it.executeQuery()
    while (resultSet.next()) {
        val content = resultSet.getString("content")
        println("- ${content} (${uuid0})")
    }
}

delete

uuid で指定した行のみを削除。

val deleteCmd = "DELETE FROM note WHERE uuid=?"
connection.prepareStatement(deleteCmd).use {
    it.setString(1, uuid0)
    it.executeUpdate()
}

note テーブルにある行を全部削除。

connection.createStatement().use {
    val cmd = "DELETE FROM note"
    it.executeUpdate(cmd)
}

まとめ

完成したコード。

@file:Repository("https://repo1.maven.org/maven2/")
@file:DependsOn("com.h2database:h2:2.2.222")

import java.io.File
import java.util.UUID
//import java.sql.Connection
//import java.sql.Statement
import org.h2.jdbcx.JdbcConnectionPool

val path = File(".").canonicalPath
val jdbcURI = "jdbc:h2:${path}/mydb"
val connectionPool = JdbcConnectionPool.create(jdbcURI, "", "")
val connection     = connectionPool.getConnection()

// create:
connection.createStatement().use {
    val cmd = listOf(
        "CREATE TABLE IF NOT EXISTS note (",
        "id BIGINT PRIMARY KEY AUTO_INCREMENT,",
        "uuid LONGVARCHAR NOT NULL,",
        "content LONGVARCHAR NOT NULL)").joinToString("")
    it.execute(cmd)
}

// insert:
val uuid0 = UUID.randomUUID().toString()
val content0 = "# Hello, World!"

val insertCmd = "INSERT INTO note(uuid, content) VALUES(?,?)"
connection.prepareStatement(insertCmd).use {
    it.setString(1, uuid0)
    it.setString(2, content0)
    it.executeUpdate()
}

// select:
connection.createStatement().use {
    val cmd = "SELECT uuid, content FROM note LIMIT 10"
    val resultSet = it.executeQuery(cmd)
    while (resultSet.next()) {
        val uuid = resultSet.getString("uuid")
        val content = resultSet.getString("content")
        println("- ${content} (${uuid})")
    }
}

// update:
val updateCmd = "UPDATE note SET content=? WHERE uuid=?"
val updateContent  = "# Hello, Again!" 
connection.prepareStatement(updateCmd).use {
    it.setString(1, updateContent)
    it.setString(2, uuid0)
    it.executeUpdate()
}

// select:
val selectCmd = "SELECT content FROM note WHERE uuid=?"
connection.prepareStatement(selectCmd).use {
    it.setString(1, uuid0)
    val resultSet = it.executeQuery()
    while (resultSet.next()) {
        val content = resultSet.getString("content")
        println("- ${content} (${uuid0})")
    }
}

// delete:
val deleteCmd = "DELETE FROM note WHERE uuid=?"
connection.prepareStatement(deleteCmd).use {
    it.setString(1, uuid0)
    it.executeUpdate()
}

// delete:
connection.createStatement().use {
    val cmd = "DELETE FROM note"
    it.executeUpdate(cmd)
}

connection.close()
connectionPool.dispose()

実行する。

$ kotlinc -script h2db.main.kts

以上です。