30
What is doobie ? - database access for scala - 2016-10-1 第十七回 #渋谷java

What is doobie? - database access for scala -

Embed Size (px)

Citation preview

Page 1: What is doobie? - database access for scala -

What is doobie ?- database access for scala -

2016-10-1第十七回 #渋谷java

Page 2: What is doobie? - database access for scala -

Me島本 多可子(@chibochibo03)

株式会社ビズリーチ CTO室

普段はScalaを書いてます

直近の著書です →

Page 3: What is doobie? - database access for scala -

Today's topic

doobieでできることをざっくり紹介

functional programming的な話はしません

scalazの細かい話はしません

Page 4: What is doobie? - database access for scala -

Background

● Slick○ ScalaでメジャーなDBアクセスライブラリ

● 色々な意見があるが・・・

弁解できないのが

Performance

Page 5: What is doobie? - database access for scala -

Hard!!

● whole query preparation timehttp://stackoverflow.com/questions/39725886/typical-performance-in-slick-ver-3-1-1

● join explain

Page 6: What is doobie? - database access for scala -

(´・ω・`)ショボーン

他を模索してみる・・・

Page 7: What is doobie? - database access for scala -

doobie

https://github.com/tpolecat/doobie

● ScalaのDBアクセスライブラリ

● ORMではない(重要)

● JDBCを使ったプログラムを書く手段を提供

Page 8: What is doobie? - database access for scala -

doobie

キーワードは

pure FP SQLI/O

Page 9: What is doobie? - database access for scala -

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

Page 10: What is doobie? - database access for scala -

doobie is pre-1.0

● 開発が活発

● 大きな変更もありえる

○ マイナーリリース(0.x)で非推奨になることも

Page 11: What is doobie? - database access for scala -

Setup

● build.sbt

libraryDependencies ++= Seq( "org.tpolecat" %% "doobie-core" % 0.3.0)

Page 12: What is doobie? - database access for scala -

Setup

● 必要なimport

import doobie.imports._import scalaz._, Scalaz._, concurrent.Task

Page 13: What is doobie? - database access for scala -

Setup

● 接続情報

val xa = DriverManagerTransactor[Task]( "org.h2.Driver", "url", "user", "password")

Page 14: What is doobie? - database access for scala -

Select

val id = 1val res = sql"select * from user where uid = $id" .query[User] .unique .transact(xa)

Page 15: What is doobie? - database access for scala -

Select

val id = 1val res = sql"select * from user where uid = $id" .query[User] .unique .transact(xa)

(注)まだ実行されてないよ!

// Query0[User]

// ConnectionIO[User]

// Task[User]

Page 16: What is doobie? - database access for scala -

Benefit

● actually constructing PreparedStatement○ SQLはPreparedStatementで実行

○ パラメータはsetString, setIntなどで設定される

● 破壊的なSQLにならない

● ソースコードだけで完結する

○ 別ファイルを行き来しなくてよい

Page 17: What is doobie? - database access for scala -

Benefit

● 非同期が前提のものとの相性がよい

○ たとえばhttp4s

val service = HttpService { case req @ GET -> Root / "users"/ IntVar(uid) => Ok(findUser(uid))}

def findUser(uid: Int): Task[User] = ...

EntityEncoderを定義すればcase classをそのまま返せる

Page 18: What is doobie? - database access for scala -

Insert

sql"insert into user (name, age) values (${u.name}, ${u.age})".update.run // ConnectionIO[Int]

Page 19: What is doobie? - database access for scala -

Insert

for { id <- sql"insert into ...".update .withUniqueGeneratedKeys[Int]("uid") _ <- sql"insert into ... values ($id, ...)".update .run} yield id

Page 20: What is doobie? - database access for scala -

特徴的な機能

Page 21: What is doobie? - database access for scala -

What is YOLO mode ?

● REPLで便利な機能

○ transact(xa)してforeach(println)するのは煩雑

● 面倒な呼び出しをショートカットできる

○ quick・・結果を標準出力に

○ check・・Typecheckingを行う(後述)

Page 22: What is doobie? - database access for scala -

YOLO - quick

import xa.yolo._

sql"select * from user where uid = $id" .query[User] .quick .unsafePerformSync

必要

// Task[Unit]

Page 23: What is doobie? - database access for scala -

Typechecking (experimental)

● DBスキーマに対してクエリを検証

○ マッピングする型が正しいか

● run-time check

Page 24: What is doobie? - database access for scala -

YOLO - check

import xa.yolo._

sql"select * from user where uid = $id" .query[User] .check .unsafePerformSync

必要

Page 25: What is doobie? - database access for scala -

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...

Page 26: What is doobie? - database access for scala -

Unit Testing (experimental)

● UTでクエリの検証をサポート

○ 現在はSpecs2のみ

● doobie-contrib-specs2を依存関係に追加

○ doobie.contrib.specs2.analysisspec.AnalysisSpecをミッ

クスイン

Page 27: What is doobie? - database access for scala -

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のインポートは不要

Page 28: What is doobie? - database access for scala -

まとめ

Page 29: What is doobie? - database access for scala -

Conclusion

● スタイル

○ SQLを書く

○ functional programming● SQLの妥当性はテストで行う

● scalazを扱うものと相性がよい

○ http4sとか

Page 30: What is doobie? - database access for scala -

Conclusion

● 前述したことがデメリットとなるケースも

● 機能が大きく変わる可能性あり

○ 1.0まで遠い・・・

● 吟味してから使いましょう