Click here to load reader
Upload
chibochibo
View
185
Download
1
Embed Size (px)
Citation preview
Statement Fragments- How to write dynamic SQL queries in doobie -
2017-01-28第十八回 #渋谷java
0.4.0 release!
● Cats Support
● Simple statement logging Support
● Changes to Add-On Modules
● Dynamic SQL
0.4.0 release!
● Cats Support
● Simple statement logging Support
● Changes to Add-On Modules
● Dynamic SQL
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)
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)
若干改善された
Setting Up
import doobie.imports._import scalaz._, Scalaz._, concurrent.Task
val xa = DriverManagerTransactor[Task]( "org.h2.Driver", "url", "user", "password")// YOLO modeimport xa.yolo._
SQL literals
val select = fr"select * from user"val where = fr"where uid = $id"
val sql = select ++ wheresql.query[User].quick.unsafePerformSync
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で定義
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
++で連結
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"
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パラメータではないもの
The Fragments Module
● some convenience combinators○ andOpt
○ orOpt
○ whereAndOpt
○ whereOrOpt
○ in
and so on
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]
)
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 "
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 = ? "
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 ? "
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]]
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 "
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 (?, ?) "
Conclusion
● 嬉しいこと
○ dynamic SQL が書けるようになった
○ 特にwhere句の組み立ては高確率で必要になる
● 悲しいこと
○ 「若干」感
○ 使い方がよくわからないもの(andOpt)
まだ0.4.xなのでこれからの進化に期待!