Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

What is doobie? - database access for scala -

812 views

Published on

2016-10-1 第十七回 #渋谷java
I introduce you to the doobie, which is database access for scala.

  • Be the first to comment

What is doobie? - database access for scala -

  1. 1. What is doobie ? - database access for scala - 2016-10-1 第十七回 #渋谷java
  2. 2. Me 島本 多可子(@chibochibo03) 株式会社ビズリーチ CTO室 普段はScalaを書いてます 直近の著書です →
  3. 3. Today's topic doobieでできることをざっくり紹介 functional programming的な話はしません scalazの細かい話はしません
  4. 4. Background ● Slick ○ ScalaでメジャーなDBアクセスライブラリ ● 色々な意見があるが・・・ 弁解できないのが Performance
  5. 5. Hard!! ● whole query preparation time http://stackoverflow.com/questions/39725886/typical-performance-in-slick-ver-3-1-1 ● join explain
  6. 6. (´・ω・`)ショボーン 他を模索してみる・・・
  7. 7. doobie https://github.com/tpolecat/doobie ● ScalaのDBアクセスライブラリ ● ORMではない(重要) ● JDBCを使ったプログラムを書く手段を提供
  8. 8. doobie キーワードは pure FP SQLI/O
  9. 9. Supported releases ● 0.3.x (最新は0.3.0) ○ JDK 1.8+ ○ Scala 2.10, 2.11, 2.12 ● 0.2.x (最新は0.2.4) ○ JDK 1.7+ ○ Scala 2.10, 2.11
  10. 10. doobie is pre-1.0 ● 開発が活発 ● 大きな変更もありえる ○ マイナーリリース(0.x)で非推奨になることも
  11. 11. Setup ● build.sbt libraryDependencies ++= Seq( "org.tpolecat" %% "doobie-core" % 0.3.0 )
  12. 12. Setup ● 必要なimport import doobie.imports._ import scalaz._, Scalaz._, concurrent.Task
  13. 13. Setup ● 接続情報 val xa = DriverManagerTransactor[Task]( "org.h2.Driver", "url", "user", "password" )
  14. 14. Select val id = 1 val res = sql"select * from user where uid = $id" .query[User] .unique .transact(xa)
  15. 15. Select val id = 1 val res = sql"select * from user where uid = $id" .query[User] .unique .transact(xa) (注)まだ実行されてないよ! // Query0[User] // ConnectionIO[User] // Task[User]
  16. 16. Benefit ● actually constructing PreparedStatement ○ SQLはPreparedStatementで実行 ○ パラメータはsetString, setIntなどで設定される ● 破壊的なSQLにならない ● ソースコードだけで完結する ○ 別ファイルを行き来しなくてよい
  17. 17. Benefit ● 非同期が前提のものとの相性がよい ○ たとえばhttp4s val service = HttpService { case req @ GET -> Root / "users"/ IntVar(uid) => Ok(findUser(uid)) } def findUser(uid: Int): Task[User] = ... EntityEncoderを定義すれば case classをそのまま返せる
  18. 18. Insert sql"insert into user (name, age) values (${u.name}, ${u.age})".update.run // ConnectionIO[Int]
  19. 19. Insert for { id <- sql"insert into ...".update .withUniqueGeneratedKeys[Int]("uid") _ <- sql"insert into ... values ($id, ...)".update .run } yield id
  20. 20. 特徴的な機能
  21. 21. What is YOLO mode ? ● REPLで便利な機能 ○ transact(xa)してforeach(println)するのは煩雑 ● 面倒な呼び出しをショートカットできる ○ quick・・結果を標準出力に ○ check・・Typecheckingを行う(後述)
  22. 22. YOLO - quick import xa.yolo._ sql"select * from user where uid = $id" .query[User] .quick .unsafePerformSync 必要 // Task[Unit]
  23. 23. Typechecking (experimental) ● DBスキーマに対してクエリを検証 ○ マッピングする型が正しいか ● run-time check
  24. 24. YOLO - check import xa.yolo._ sql"select * from user where uid = $id" .query[User] .check .unsafePerformSync 必要
  25. 25. YOLO - check ✓ SQL Compiles and Typechecks ✕ C01 UID INTEGER (INTEGER) NOT NULL → String - INTEGER (INTEGER) is ostensibly coercible to String according to the JDBC specification but is not a recommended target type. Fix this by changing the schema type to CHAR or VARCHAR; or the Scala type to Int or JdbcType. ✓ C02 NAME VARCHAR (VARCHAR) NOT NULL → String ...
  26. 26. Unit Testing (experimental) ● UTでクエリの検証をサポート ○ 現在はSpecs2のみ ● doobie-contrib-specs2を依存関係に追加 ○ doobie.contrib.specs2.analysisspec.AnalysisSpecをミッ クスイン
  27. 27. Unit Testing (experimental) object xxx extends Specification with AnalysisSpec { val transactor = DriverManagerTransactor[Task]( "org.mysql.jdbc.Driver", "url", "user", "password" ) check(sql"select * from user".query[User]) } (注)存在するスキーマに対して実行 yoloのインポートは不要
  28. 28. まとめ
  29. 29. Conclusion ● スタイル ○ SQLを書く ○ functional programming ● SQLの妥当性はテストで行う ● scalazを扱うものと相性がよい ○ http4sとか
  30. 30. Conclusion ● 前述したことがデメリットとなるケースも ● 機能が大きく変わる可能性あり ○ 1.0まで遠い・・・ ● 吟味してから使いましょう

×