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.

Dynamic SQL in doobie

487 views

Published on

2017-01-28 第十八回 #渋谷java
I introduce you to the dynamic SQL in doobie, which is one of new for version 0.4.0.

  • Be the first to comment

Dynamic SQL in doobie

  1. 1. Statement Fragments - How to write dynamic SQL queries in doobie - 2017-01-28 第十八回 #渋谷java
  2. 2. 0.4.0 release! ● Cats Support ● Simple statement logging Support ● Changes to Add-On Modules ● Dynamic SQL
  3. 3. 0.4.0 release! ● Cats Support ● Simple statement logging Support ● Changes to Add-On Modules ● Dynamic SQL
  4. 4. 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)
  5. 5. 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) 若干改善された
  6. 6. Setting Up import doobie.imports._ import scalaz._, Scalaz._, concurrent.Task val xa = DriverManagerTransactor[Task]( "org.h2.Driver", "url", "user", "password" ) // YOLO mode import xa.yolo._
  7. 7. SQL literals val select = fr"select * from user" val where = fr"where uid = $id" val sql = select ++ where sql.query[User].quick.unsafePerformSync
  8. 8. SQL literals val select: Fragment = fr"select * from user" val where: Fragment = fr"where uid = $id" val sql: Fragment = select ++ where sql.query[User].quick.unsafePerformSync sqlの代わりにfrで定義
  9. 9. SQL literals val select: Fragment = fr"select * from user" val where: Fragment = fr"where uid = $id" val sql: Fragment = select ++ where sql.query[User].quick.unsafePerformSync ++で連結
  10. 10. 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"
  11. 11. 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パラメータではないもの
  12. 12. The Fragments Module ● some convenience combinators ○ andOpt ○ orOpt ○ whereAndOpt ○ whereOrOpt ○ in and so on
  13. 13. 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] )
  14. 14. The Fragments Module - whereAndOpt import Fragments._ val uid: Option[Int] = None val json: Option[String] = None 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 "
  15. 15. The Fragments Module - whereAndOpt import Fragments._ val uid: Option[Int] = Some(1) val json: Option[String] = None 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 = ? "
  16. 16. 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 ? "
  17. 17. 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]]
  18. 18. The Fragments Module - in import Fragments._ val uids: List[Int] = Nil val sql = fr"select * from user" ++ whereAndOpt( uids.toNel.map(p => in(fr"uid", p))// Option[Fragment] ) // "select * from user "
  19. 19. 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 (?, ?) "
  20. 20. Conclusion ● 嬉しいこと ○ dynamic SQL が書けるようになった ○ 特にwhere句の組み立ては高確率で必要になる ● 悲しいこと ○ 「若干」感 ○ 使い方がよくわからないもの(andOpt) まだ0.4.xなのでこれからの進化に期待!

×