LoginSignup
8

More than 5 years have passed since last update.

KotlinからExposedを使ってSQLiteを操作する

Last updated at Posted at 2017-12-13

追記

こちらのコメントに書かれているように、この記事のハマったところは、現在はExposedの公式FAQにて言及されているようです。
Kotlinに関する情報が増えてきたことで、ますますとっつきやすい言語になっているという実感があります!
以上追記終わり!

はじめに

KotlinでSQLを操作するととても気持ちいいという噂を聞きまして、実証すべくお手軽なSQLiteを用いてやってみることにしました。
今回はローカルに置かれたSQLiteを使います。

環境

  • IntelliJIDEA 2017.3
  • Kotlin 1.2.0
  • exposed 0.9.1

Gradle

buildscript {
    ext.kotlin_version = '1.2.0'

    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath group: 'org.xerial', name: 'sqlite-jdbc', version: "3.21.0"
    }
}

group 'mayoneko'
version '1.0-SNAPSHOT'

apply plugin: 'kotlin'

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

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    compile 'org.jetbrains.exposed:exposed:0.9.1'
    compile 'org.slf4j:slf4j-simple:+' //ないと怒られるから入れておくけどなくても動く
    runtime group: 'org.xerial', name: 'sqlite-jdbc', version: '3.21.0'
}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

ソースコード


import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SchemaUtils.create
import org.jetbrains.exposed.sql.transactions.transaction
import java.sql.Connection

object Members: Table() {
    val id=integer("id").autoIncrement().primaryKey()
    val name=text("name")
    val old=integer("old")
    val hoge=bool("hoge")
    val count=integer("count")
}

fun main(args: Array<String>) {
    Database.connect("jdbc:sqlite:C:/Users/僕の名前/Documents/KotlinFolder/Kotlin-SQLite-test/test.sqlite", "org.sqlite.JDBC")
    transaction(transactionIsolation = Connection.TRANSACTION_SERIALIZABLE, repetitionAttempts = 3) {
        create(Members)
        Members.insert {
            it[name]="taro"
            it[old]=22
            it[hoge]=false
            it[count]=2
        }
        Members.insert {
            it[name]="hanako"
            it[old]=21
            it[hoge]=false
            it[count]=5
        }
        Members.insert {
            it[name]="hogeko"
            it[old]=58
            it[hoge]=true
            it[count]=10
        }
        Members.insert {
            it[name]="hogeo"
            it[old]=19
            it[hoge]=true
            it[count]=15
        }
        Members.insert {
            it[name]="goro"
            it[old]=29
            it[hoge]=false
            it[count]=3
        }
        Members.insert {
            it[name]="hogejiro"
            it[old]=37
            it[hoge]=true
            it[count]=7
        }
        for (line in Members.selectAll()){
            for (data in line.data){
                print(data)
            }
            println()
        }
        Members.select {
            Members.hoge.eq(true)
        }.forEach {
            println("${it[Members.name]}は${it[Members.old]}歳のhogeです")
        }
    }
}

はまったところ

  • サンプル通りにtransactionを引数なしで指定すると、エラーが出る。
    • SQLiteはTRANSACTION_SERIALIZABLETRANSACTION_READ_UNCOMMITTEDでしか動かない
    • transaction関数の引数の一つ目にConnection.TRANSACTION_SERIALIZABLEを指定する
    • デフォルトはConnection.TRANSACTION_REPEATABLE_READ
  • transaction関数の二つ目の引数が分からない
    • repetitionAttemptsというInt型の引数を取るらしい。
    • Exposedのソースコードに書いてある3をよく分からないままに入れたらうまく動いた。

発展

kotlinx.htmlのライブラリと一緒に使うとtableの表示なんかが楽しく書けるので、そっちもやってみました。サーバーにはSparkFrameworkを利用しています。

ソースコード


import spark.Spark.get
import kotlinx.html.*
import kotlinx.html.stream.createHTML
import org.jetbrains.exposed.sql.Database
import org.jetbrains.exposed.sql.SchemaUtils.create
import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.selectAll
import org.jetbrains.exposed.sql.transactions.transaction
import java.sql.Connection

object Student : Table("student") {
    val id = integer("student_id").autoIncrement().primaryKey()
    val name = varchar("name", 50)
    val grade = integer("grade")
}

fun main(args: Array<String>) {

    Database.connect("jdbc:sqlite:C:/Users/僕の名前/Documents/KotlinFolder/Kotlin-HTML-test/test.sqlite", "org.sqlite.JDBC")
    transaction(transactionIsolation = Connection.TRANSACTION_SERIALIZABLE, repetitionAttempts = 3) {
        create(Student)
        Student.insert {
            it[name] = "taro"
            it[grade] = 3
        }
        Student.insert {
            it[name] = "hanako"
            it[grade] = 2
        }
        Student.insert {
            it[name] = "hogeo"
            it[grade] = 1
        }
        val text = createHTML().html {
            head {
                meta(charset = "UTF-8")
                title {
                    +"Kotlin-HTML-test"
                }
                style {
                    +"table,td{border:solid 1px #000000; border-collapse:collapse;}"
                }
            }
            body {
                table {
                    for (line in Student.selectAll()) {
                        tr {
                            for (content in line.data) {
                                td { +"$content" }
                            }
                        }
                    }
                }
            }
        }
        val index = createHTML().html {
            head {
                meta(charset = "UTF-8")
                title { +"こんにちは" }
            }
            body {
                a(href = "/hello") { +"こちらへ" }
            }
        }

        get("/") { request, response ->
            index
        }
        get("/hello") { request, response ->
            text
        }
    }
}

楽しいKotlin

参考にしたサイト

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
8