#備忘録
*自分に向けて書いた備忘録
変なところが多々あると思うのでご指摘お願いします。
#プロジェクト作成
今回はあえてSpring Initializrを使ってプロジェクトの雛形を作ってもらいます
Gradle Project with Kotlin
にして作成.
##プロジェクトを開く
作成したプロジェクトを開きます
なんでもいいですがintelliJがオススメですね!
学生は有料版も無料で使えるみたいです
##gradleファイル設定
build.gradleにsparkの依存関係を記述します。sqlとORMもすでに記述しています。
多分余計なものたくさんあります・・・
このファイル内のspring関係は削除しちゃってください笑
元あるものを全消ししてこれを貼り付ける時、import org.~~.classpathみたいなのが出てきたらOKをする
これをしないとクラスパスがうまく設定できなくて後々実行できなくなります。
buildscript {
ext {
kotlinVersion = '1.2.10'
springBootVersion = '1.5.9.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}")
}
}
apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
repositories {
mavenCentral()
maven {
url('https://dl.bintray.com/kotlin/exposed/')
}
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
compile("org.jetbrains.kotlin:kotlin-stdlib-jre8:${kotlinVersion}")
compile("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
testCompile('org.springframework.boot:spring-boot-starter-test')
compile 'mysql:mysql-connector-java:5.1.6'
compile 'com.sparkjava:spark-core:2.6.0'
runtime "org.jetbrains.kotlin:kotlin-reflect:0.13.1513"
runtime group: 'org.jetbrains.exposed', name: 'exposed', version: '0.8.5'
compile group: 'org.jetbrains.exposed', name: 'spring-transaction', version: '0.8.5'
}
src/main/kotlin/com.example.demo
の中にあるDemoApplication.ktをいじります
package com.example.demo
import spark.Spark.*
fun main(args: Array<String>) {
get("/hello"){ _, _->
"hello world"
}
}
簡単にhello worldしましょう。
初期状態ではspringプロジェクトを起動しようとするので、Demo~~.ktの画面で右クリックでDebugかRunしてくれれば起動できます。
起動できたらhttp://localhost:4567/hello でhello world完了です。
#データベースを取り入れる
##テーブルの作成
サンプルとしてローカルのdbにuserテーブルを作成して、そのテーブルを操作します。
package model
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.*
object User_t : Table("users") {
val id = integer("id").autoIncrement().primaryKey()
val name = varchar("name", 50).uniqueIndex()
}
data class User(
var id : Int = 0,
var name : String? = null
)
kotlinのORM,exposedを使います
まずはローカルのdbにコネクトしuserテーブルをcreateします
今回はmysqlを使っているので、sqlでcreate database [db名]
でデータベースを作成します.
package db
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.SchemaUtils.create
import model.*
fun DBconnect(){
Database.connect("jdbc:mysql://localhost/[DB名]", "com.mysql.jdbc.Driver","ユーザー名","パスワード")
transaction {
create(User_t)
}
}
Demo~.ktにconnectを追加します。
package com.example.demo
import spark.Spark.*
import db.DBconnect
fun main(args: Array<String>) {
DBconnect()
get("/hello"){ _, _->
"hello world"
}
}
これで実行すればdbにusersテーブルが作成されているはず・・・!
データを追加する
今回はhttpのリクエストボディから名前を取り出しusersテーブルに格納していこうと思います。
レスポンスをjsonに直すのに以下のファイルが必要になるので追加します。
package com.example.demo
import com.fasterxml.jackson.databind.ObjectMapper
import spark.ResponseTransformer
class JsonTransformer(private val objectMapper: ObjectMapper) : ResponseTransformer {
override fun render(model: Any?): String =
objectMapper.writeValueAsString(model)
}
以下をmainの中に記述してください。DBconnectの後あたりに・・・
path("/users"){
post("", UserController().addUser(),JsonTransformer(ObjectMapper().registerKotlinModule()))
}
リクエストを処理したいのでcontrollerを以下の様に用意
package controller
import spark.*
import com.fasterxml.jackson.module.kotlin.readValue
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
class UserController {
fun addUser(): Route = Route { req, _ ->
model.AddUser(jacksonObjectMapper().readValue(req.body()))
}
}
マッパーがリクエストボディから値を取り出してマッピングしてくれるので、そのままmodelの関数にぶち込みます。
user.kt
に以下を追加して実行してみます。
fun AddUser(user: User): User{
transaction {
user.id = User_t.insert {
it[User_t.name] = user.name
} get User_t.id
}
return user
}
postmanやらなんやらを使ってpostするとjsonが返ってきます。
content-typeを指定しないとjsonだと認識してくれませんけど・・・そこは割愛
最後にgithubあげるんでそこをみてもらえるとよいです。
##データを取得する
paramにidを指定したユーザ取得と、全ユーザの取得を行います。
path("/users"){
post("", UserController().addUser(), JsonTransformer(ObjectMapper().registerKotlinModule()))
get("/:id",UserController().getUser(),JsonTransformer(ObjectMapper().registerKotlinModule()))
get("",UserController().getUserList(),JsonTransformer(ObjectMapper().registerKotlinModule()))
}
fun GetUser(id : Int): User{
lateinit var user : User
transaction {
User_t.select {
User_t.id.eq(id)
}.forEach {
user = User(it[User_t.id],it[User_t.name])
}
}
return user
}
fun GetUserList():MutableList<User>{
lateinit var user : User
val userList : MutableList<User> = mutableListOf()
transaction {
User_t.selectAll().forEach {
user = User(it[User_t.id],it[User_t.name])
userList += user
}
}
return userList
}
fun getUser(): Route = Route { req, _ ->
model.GetUser(req.params("id").toInt())
}
fun getUserList(): Route = Route { _, _ ->
model.GetUserList()
}
それぞれこんな感じで追加すればいけます。
http://localhost:4567/users/2 は
{"id":1,"name":"sample1"}
http://localhost:4567/users は
[{"id":1,"name":"sample1"},{"id":2,"name":"サンプル2"}]
こんな感じで取れれば成功です。
ソースコードはこちらに上げています。
https://github.com/mr04vv/kotlin_spark_demo
#exposedについて
joinしたい時は、テーブル定義の箇所を以下の様にします。
object GroupMember_t : Table("group_members") {
val id = integer("id").autoIncrement().primaryKey()
val group_id = integer("group_id")
val user_id = (integer("user_id") references User_t.id)
}
references User_t.id
という依存関係を明記して上げないとjoinできません・・・
joinの例はこんな感じ
transaction{
(GroupMember_t innerJoin User_t).slice(User_t.id,User_t.name).
select{
GroupMember_t.group_id.eq(group)
}.forEach{
user = GroupMember(it[User_t.id],it[User_t.name])
users += user
}
}
exposedのドキュメントがほとんど無くて結構躓きました・・・