追記
こちらのコメントに書かれているように、この記事のハマったところは、現在は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_SERIALIZABLE
かTRANSACTION_READ_UNCOMMITTED
でしか動かない -
transaction
関数の引数の一つ目にConnection.TRANSACTION_SERIALIZABLE
を指定する - デフォルトは
Connection.TRANSACTION_REPEATABLE_READ
- SQLiteは
-
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