20

Click here to load reader

Dynamic SQL in doobie

Embed Size (px)

Citation preview

Page 1: Dynamic SQL in doobie

Statement Fragments- How to write dynamic SQL queries in doobie -

2017-01-28第十八回 #渋谷java

Page 2: Dynamic SQL in doobie

0.4.0 release!

● Cats Support

● Simple statement logging Support

● Changes to Add-On Modules

● Dynamic SQL

Page 3: Dynamic SQL in doobie

0.4.0 release!

● Cats Support

● Simple statement logging Support

● Changes to Add-On Modules

● Dynamic SQL

Page 4: Dynamic SQL in doobie

The dynamic SQL story

The dynamic SQL story is now slightly better with the introduction of composable statement fragments.

"Changes to Core". changelog. https://github.com/tpolecat/doobie/blob/series/0.4.x/CHANGELOG.md#changes-to-core, (参照 2017-01-25)

Page 5: Dynamic SQL in doobie

The dynamic SQL story

The dynamic SQL story is now slightly better with the introduction of composable statement fragments.

"Changes to Core". changelog. https://github.com/tpolecat/doobie/blob/series/0.4.x/CHANGELOG.md#changes-to-core, (参照 2017-01-25)

若干改善された

Page 6: Dynamic SQL in doobie

Setting Up

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

val xa = DriverManagerTransactor[Task]( "org.h2.Driver", "url", "user", "password")// YOLO modeimport xa.yolo._

Page 7: Dynamic SQL in doobie

SQL literals

val select = fr"select * from user"val where = fr"where uid = $id"

val sql = select ++ wheresql.query[User].quick.unsafePerformSync

Page 8: Dynamic SQL in doobie

SQL literals

val select: Fragment = fr"select * from user"val where: Fragment = fr"where uid = $id"

val sql: Fragment = select ++ wheresql.query[User].quick.unsafePerformSync

sqlの代わりに frで定義

Page 9: Dynamic SQL in doobie

SQL literals

val select: Fragment = fr"select * from user"val where: Fragment = fr"where uid = $id"

val sql: Fragment = select ++ wheresql.query[User].quick.unsafePerformSync

++で連結

Page 10: Dynamic SQL in doobie

An arbitrary string value

val table = "user"

val select = fr"select * from"val sql = select ++ Fragment.const(table)

sql.query[Unit].sql// "select * from user"

Page 11: Dynamic SQL in doobie

An arbitrary string value

val table = "user"

val select = fr"select * from"val sql = select ++ Fragment.const(table)

sql.query[Unit].sql// "select * from user"SQLパラメータではないもの

Page 12: Dynamic SQL in doobie

The Fragments Module

● some convenience combinators○ andOpt

○ orOpt

○ whereAndOpt

○ whereOrOpt

○ in

and so on

Page 13: Dynamic SQL in doobie

The Fragments Module - whereAndOpt

import Fragments._

val uid: Option[Int] = ...val json: Option[String] = ...val sql = fr"select * from user" ++ whereAndOpt( uid.map(p => fr"uid = $p"), // Option[Fragment]

json.map(p => fr"json like $p") // Option[Fragment]

)

Page 14: Dynamic SQL in doobie

The Fragments Module - whereAndOpt

import Fragments._

val uid: Option[Int] = Noneval json: Option[String] = Noneval sql = fr"select * from user" ++ whereAndOpt( uid.map(p => fr"uid = $p"), // Option[Fragment]

json.map(p => fr"json like $p") // Option[Fragment]

)// "select * from user "

Page 15: Dynamic SQL in doobie

The Fragments Module - whereAndOpt

import Fragments._

val uid: Option[Int] = Some(1)val json: Option[String] = Noneval sql = fr"select * from user" ++ whereAndOpt( uid.map(p => fr"uid = $p"), // Option[Fragment]

json.map(p => fr"json like $p") // Option[Fragment]

)// "select * from user WHERE uid = ? "

Page 16: Dynamic SQL in doobie

The Fragments Module - whereAndOpt

import Fragments._

val uid: Option[Int] = Some(1)val json: Option[String] = Some("%foo%")val sql = fr"select * from user" ++ whereAndOpt( uid.map(p => fr"uid = $p"), // Option[Fragment]

json.map(p => fr"json like $p") // Option[Fragment]

)// "select * from user WHERE uid = ? AND json like ? "

Page 17: Dynamic SQL in doobie

The Fragments Module - in

import Fragments._

val uids: List[Int] = ...val sql = fr"select * from user" ++ whereAndOpt( uids.toNel.map(p => in(fr"uid", p))// Option[Fragment] )

Option[NonEmptyList[Int]]

Page 18: Dynamic SQL in doobie

The Fragments Module - in

import Fragments._

val uids: List[Int] = Nilval sql = fr"select * from user" ++ whereAndOpt( uids.toNel.map(p => in(fr"uid", p))// Option[Fragment] )// "select * from user "

Page 19: Dynamic SQL in doobie

The Fragments Module - in

import Fragments._

val uids: List[Int] = List(1,10)val sql = fr"select * from user" ++ whereAndOpt( uids.toNel.map(p => in(fr"uid", p))// Option[Fragment] )// "select * from user WHERE uid IN (?, ?) "

Page 20: Dynamic SQL in doobie

Conclusion

● 嬉しいこと

○ dynamic SQL が書けるようになった

○ 特にwhere句の組み立ては高確率で必要になる

● 悲しいこと

○ 「若干」感

○ 使い方がよくわからないもの(andOpt)

まだ0.4.xなのでこれからの進化に期待!