takezoeさんがquillを紹介していたので、
Scalaの新しいデータベースアクセスライブラリ「quill」を試してみた - たけぞう瀕死ブログ
実際にどんな感じで使えるのかを試してみました。
http://getquill.io/getquill.io
結論、Slick2系から置き換えるのはなかなかありかなと思っています。
直接的なクエリサンプルは、上記のtakezoeさんのブログやドキュメントに書いてあるので、もうちょっと踏み込んだ内容を紹介したいと思います。
Database Access
今回は自分がよく使うMySQLにアクセスするように試しました。
動かすのに必要な最低限のlibraryは以下です。
libraryDependencies ++= { Seq( "mysql" % "mysql-connector-java" % "5.1.36", "io.getquill" %% "quill-jdbc" % "0.4.2-SNAPSHOT", "com.zaxxer" % "HikariCP" % "2.4.3", "com.typesafe" % "config" % "1.3.0" ) }
HikariCPとTypesafeConfigがないと、動きません。
また、このバージョンの場合、Java8でないと動きません。
build.sbtを上記のように作って上げれば、ドキュメントに書いてあるようなクエリをコンパイルすることができます。
quill_example/UserDao.scala at master · moc-yuto/quill_example · GitHub
テーブル名
Slickと違ってテーブル名を文字列で指定する部分はなく、queryのcase classがそのままテーブル名に使われます。
以下の例だと、case classのUsersがそのままテーブル名として使われます。
case class Users(id: Int, name: String, age: Int) val find = quote { (id: Int) => query[Users].filter(u => u.id == id) }
トランザクション
やはり、実践投入するならトランザクション処理は必須となりますが、本家ドキュメントには書かれていません。
しかし、テストコードにはしっかり書かれています。
書き方としてはとても単純で、以下のようにtransaction関数でくくってあげればいいだけです。
db.transaction{ val a = db.run(UserDao.findName)(name).headOption if (a.isEmpty) db.run(UserDao.insert)(name, age) else db.run(UserDao.update)(a.get.id, age) throw new Exception }
このように書くと以下の様なクエリが流れました。
2016-03-06T15:29:28.783495Z 13 Query SET autocommit=1 2016-03-06T15:29:28.783727Z 13 Query set session transaction read write 2016-03-06T15:29:28.783987Z 13 Query SELECT @@session.tx_isolation 2016-03-06T15:29:28.828915Z 4 Query SELECT x1.id, x1.name, x1.age FROM users x1 WHERE x1.name = 'aaa' 2016-03-06T15:29:28.875733Z 4 Query select @@session.tx_read_only 2016-03-06T15:29:28.877008Z 4 Query select @@session.tx_read_only 2016-03-06T15:29:28.877849Z 4 Query UPDATE users SET age = 1323 WHERE id = 2 2016-03-06T15:29:28.890415Z 4 Query rollback 2016-03-06T15:29:28.891274Z 4 Query SET autocommit=1
実際のトランザクションのコードは以下です。
quill_example/Users.scala at master · moc-yuto/quill_example · GitHub
感想
Slickよりも冗長な部分が減ったな―と感じます。
それでいてSlick風な書き方なので、書きやすいと思います。
また、Slickでは生成できないSQLを作れるDSLが多数あるので、細かいハンドリングがしやすいと感じました。
以下は動かしたサンプルです。
github.com