Transcript
Doma2 with Kotlin
【7/9(土)】Doma勉強会 in 東京
@yy_yank
こいつです
・viとサクラエディタ好き
・小物SIer ・JavaとKotlinが好き
ヤンク(@yy_yank)
自己紹介
とつぜんですがワタクシ、
Doma2のコントリビューターなんです
fix typo(ドヤッ)
はい、すいませんでした
with
with
with
with
Doma2、Kotlinでも使えるよ!!!の話
(一応・・・) Doma とは
・めっちゃ良いORM・Domain Oriented Database MApping Framework・Annotation Processingでのコンパイルチェック素敵
・JRE 8以上でうごく
・2Way-SQL
※NASAではない
(一応・・・) Kotlinとは
・JVM言語
・JetBrains製・Gradleスクリプトも書ける(ようになる)・Spring Initializrでも選択可能
・Null Safety(らしい)
・ScalaとGroovyのいいとこどり(らしい)
※ボクは昔のロゴの方が好き
アジェンダ
Doma2 ・Entity ・Embeddable ・Domain ・DaoKotlin ・kapt ・java.util.stream.Stream
アジェンダ
Doma2 ・Entity ・Embeddable ・Domain ・DaoKotlin ・kapt ・java.util.stream.Stream
Entity@Entity(immutable = true)data class Person( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Int? = null, val name: Name, val age: Int?, val address: Address, @Version val version: Int = -1)
アジェンダ
Doma2 ・Entity ・Embeddable ・Domain ・DaoKotlin ・kapt ・java.util.stream.Stream
・
Embeddable
package sample
import org.seasar.doma.Embeddable
@Embeddabledata class Address(val city: String, val street: String)
アジェンダ
Doma2 ・Entity ・Embeddable ・Domain ・DaoKotlin ・kapt ・java.util.stream.Stream
package sample
import org.seasar.doma.Domain
@Domain(valueType = String::class)data class Name(val value: String)
Domain
アジェンダ
Doma2 ・Entity ・Embeddable ・Domain ・DaoKotlin ・kapt ・java.util.stream.Stream
Daopackage sample
import org.seasar.doma.*import org.seasar.doma.jdbc.Result
@Dao(config = AppConfig::class)interface PersonDao { @Script fun create() @Script fun drop() @Select fun selectById(@ParameterName("id") id:Int): Person @Insert fun insert(person: Person): Result<Person> @Update fun update(person: Person): Result<Person> @Delete fun delete(person: Person): Result<Person>}
@Dao(config = AppConfig::class)interface PersonDao {
@Script fun create() @Script fun drop()
Dao
@Select fun selectById(@ParameterName("id") id:Int): Person
@Insert fun insert(person: Person): Result<Person>
Dao
@Update fun update(person: Person): Result<Person> @Delete fun delete(person: Person): Result<Person>
Dao
特に言うことなし
(別にKotlinじゃなくても)コードがシンプルでキレイ
あえていうならgettter/setterが消えてLombokぐらいの活躍はしている!
コードは全て
https://github.com/domaframework/kotlin-sample
から拝借しました!
DomaのKotlinサポートのページに詳しく指針が出ているので迷うことなし!
http://doma.readthedocs.io/ja/stable/kotlin-support/
Kotlinサポート
ざっくり言うと
・data class使おう
・イミュータブルなクラスにしよう
・コンストラクタは1つだけにしよう
・kaptにハマったら@DaoはJavaにするなど
混在させるのもアリ
アジェンダ
Doma2 ・Entity ・Embeddable ・Domain ・DaoKotlin ・kapt ・java.util.stream.Stream
・kaptはJSR269をKotlinでも使えるようにしてくれる
コンパイルツール(個人的にはaptってやめて欲しい名前)・Doma 2のAnnotation Processingに対応している
・以前のツラミ->backpaper0さんの資料
http://backpaper0.github.io/ghosts/kotlin-doma.html・Kotlinの最新version 1.0.3で改善されたりしてる
・Doma 2としてもサポートしてくれていて
ツラミ減
kapt
kaptのツラミ(backpaper0さん資料抜粋)
・少なくとも1つ注釈処理のつくJavaクラスが必要問題
→解消されたっぽい!
・arg0、arg1問題
→@ParameterNameで解消
多分これのおかげです(よね?)
kaptのツラミ
GitHubのissueにもあったのでこれで間違いなさそう
・issuehttps://github.com/domaframework/doma/issues/129
・javadochttp://doma.seasar.org/apidocs/org/seasar/doma/ParameterName.html
kaptのツラミ
@Select fun selectById(@ParameterName("id") id:Int): Person
kaptのツラミ
@ParameterNameによりarg1、arg2...問題が解消された
アジェンダ
Doma2 ・Entity ・Embeddable ・Domain ・DaoKotlin ・kapt ・java.util.stream.Stream
・KotlinはJDK6対応
・JDK8対応はまだらしい
・でもボクはJavaでいう
@SelectR select(Integer id, Function<Stream<T>, R> mapper)したい!!!!
java.util.stream.Stream
・KotlinはJDK6対応
・JDK8対応はまだらしい
・でもボクはJavaでいう
@SelectR select(Integer id, Function<Stream<T>, R> mapper)したい!!!!
ということで検証
java.util.stream.Stream
結論:出来た(なんでか分かんないけど普通に動くっぽい)
結論:出来た(でもKotlinからStream API使いにくい)
@Select(strategy = SelectType.STREAM) fun selectById( @ParameterName("id") id:Int, func :java.util.function.Function<java.util.stream.Stream<Person>, Name>): Name
Dao
@Test fun test2() { tm.required { val personName = dao.selectById(1, Function { it.map {it.name}.findFirst().orElseThrow { Exception("あってほしい!") } }) Assert.assertEquals(Name("SMITH"), personName) }}
Test Code
@Test fun test2() { tm.required { val personName = dao.selectById(1, Function { it.map {it.name}.findFirst().orElseThrow { Exception("あってほしい!") } }) Assert.assertEquals(Name("SMITH"), personName) }}
Test CodeSAM(Single Abstract Method)
@Test fun test2() { tm.required { val personName = dao.selectById(1, Function { it.map {it.name}.findFirst().orElseThrow { Exception("あってほしい!") } }) Assert.assertEquals(Name("SMITH"), personName) }}
Test CodeFunction#applyをFunction{}とかける
@Test fun test2() { tm.required { val personName = dao.selectById(1, Function { it.map {it.name}.findFirst().orElseThrow { Exception("あってほしい!") } }) Assert.assertEquals(Name("SMITH"), personName) }}
Test Codeit = Stream<Person>stream -> streamと思ってくれれば。
@Test fun test2() { tm.required { val personName = dao.selectById(1, Function { it.map {it.name}.findFirst().orElseThrow { Exception("あってほしい!") } }) Assert.assertEquals(Name("SMITH"), personName) }}
Test Code Javaで書くならstream -> stream.map(person -> person.getName()).findFirst().orElseThrow(()-> throw new Exception(“あってほしい! ”)
うん。。
でもどうせならKotlin的には。。
@Select(strategy = SelectType.STREAM) fun selectById( @ParameterName("id") id:Int, func : (person : Person) -> Name): Name
Dao
@Select(strategy = SelectType.STREAM) fun selectById( @ParameterName("id") id:Int, func : (person : Person) -> Name): Name
Dao
ここをこうして
@Test fun test2() { tm.required { val personName = dao.selectById(1, {it.name}) Assert.assertEquals(Name("SMITH"), personName) }}
Test Code
@Test fun test2() { tm.required { val personName = dao.selectById(1, {it.name}) Assert.assertEquals(Name("SMITH"), personName) }}
Test Codeこうじゃ
エラー: [DOMA4247] @Selectのstrategy要素に
SelectStrategyType.STREAMを設定した場合、
Function型のパラメータが必要です。 at sample.PersonDao.selectByIdエラー1個
Domaさん賢い!!!!
#そこじゃない
・Doma2はKotlinでも普通に使える
・手軽な感じでコード書くには良いのかも
・KotlinからStream APIは使いにくい
(あんまりDoma2関係ない)・でもJavaで使ってもDoma2は充分気持ち良い
・お世辞じゃなくDoma2は素敵
・対応の早さ、柔軟さも素敵
まとめ
Domaは素敵!!!!
top related