非同期 JDBC in Scala
@seratch
Kazuhiro Sera
Really?
え、ホントに?
JDBC?
JDBC はブロックするって
聞いてたんだけど?
Exactly
ええ、その通りです。
   ミ ヽヽヽリリノノノノ
   彡ミイ  ̄ ̄'` ̄ヾミ
   彡ミi )      ;|ミ
   彡ミ〉 _,,,,,,,,, i,i ,,,,,_イミ  JDBC と言ったな、
    rミi  _-・- l-・-、v
    {6〈`┬  、_」_  イ   あれは嘘だ。
   ヾ|  (  ,-ー-、) |
    \ `- ͡-´ノ 、 '  ’
    /i\ __ノ - ∩_____ ’
   /\_  _ノ\   ( イ___ヨ - パッ
  (_Y  ヽノ )イ͡ニ ,ノ  
  (  )____/ `ー-ー´   
ー-',..-'ー.-,ー!..ー,,-._ー.,-ー.,-ー-...,,____
   l         |   i       i   ''i,,_
JDBC っぽい non-blocking
な DB アクセス in Scala
@seratch
Kazuhiro Sera
ScalikeJDBC 
- Scala の DB アクセスライブラリ
- “仕事で使っても詰まない”
- SQL 書ける、柔軟性、拡張性、スピー
ディなバグ対応・リリース、日本語
- Slick、Squeryl ほど有名じゃないけ
ど、結構イケる感じです
DSL で書いた例
import scalikejdbc._, SQLInterpolation._
val memberId = 123
val member = DB readOnly { implicit session =>
withSQL {
select.from(Member as m)
.where.eq(m.id, memberId).and.isNull(m.deletedAt)
}.map(Member(m)).single.apply()
}
生 SQL も書けるよ
import scalikejdbc._, SQLInterpolation._
val memberId = 123
val member = DB readOnly { implicit session =>
sql”””select id, name from member
where id = ${memberId} and deleted_at is null”””
.map(Member(m)).single.apply()
}
Get things done
- わかりやすくて、ハマりにくい
- 独自のノウハウを探しまわる必要なし
- 1 人目のちゃんと使える人の確保が容易
(Scala の基本と SQL のみ)
- Cookbook(日本語)販売中
Productive
- ほぼタイプセーフな API を提供
- sbt プラグインでソースコード自動生成
- スロークエリ、Fluentd にも送れる
- specs2、ScalaTest それぞれに
AutoRollback サポート
Main subject
で、そろそろ本題。
ScalikeJDBC-Async
- ScalikeJDBC の API 互換だけど内部は
JDBC じゃない
- Activate という他のライブラリに触発
されて実装した(2013/7)
- 国内外でのいくつか利用事例を認識して
いますが、一応まだアルファバージョン
How?
- postgresql-async/mysql-async by
@mauricio をラップした
- Netty ベースの独自ドライバ
- queue を持った ConnectionPool
- Transaction は Connection を占有し
て実現(begin/commit 自前で発行)
ほぼそのまま!
import scalikejdbc._, SQLInterpolation._, async._
val memberId = 123
val member = AsyncDB withPool { implicit session =>
withSQL {
select.from(Member as m)
.where.eq(m.id, memberId).and.isNull(m.deletedAt)
}.map(Member(m)).single.future()
}
Tx は for 式で
val name = “Typesafe”
val programmers = Seq(“Alice”, “Bob”, “Chris”)
val resultFuture = AsyncDB localTx { implicit tx =>
for {
company <- Company.create(name)
employees <- company.hireAll(programmers)
} yield ()
}
Tips
- Future[Option[_]] や Future[List[_]]
だらけになるので for 式で書くとよい
- Play2 は Controller の Action に
Future のまま渡せるのでやりやすい
OMT?
LT なのに One more thing 的なアレ。
Really Must?
確かに JDBC がブロックして
困るアプリの開発もあるが
そうじゃないものの方が多い
というのが現実(リアル)では?
Most cases?
- うちのアプリ、実際 Servlet + JDBC で
十分さばけてる(知ってた)
- Reactive? C10K? 何それおいしいの?
- 実は普通の管理画面作りたいだけ
- Java は得意だけど今更の Java 感
Rails? 
実際、フロントエンドの合理的な選択。
私自身 Java でできた API サーバと
Rails フロントエンドがメインのお仕事。
でも、今日ここにいる皆さんはきっと
できれば Scala がいいんですよね・・
Grails? 
SI 業界な事情があるところ以外は
「だったらもう Rails で(ry」と思うけど
ともあれ、今日ここにいる皆さんは
Groovy より Scala ですよね・・
Play2? 
Play2 は発展途上 & Reactive 指向。
見た目から Play1/Rails 的なものを期待して
ミスマッチになっていないか?
管理画面つくるの Play2 で本当に楽?
Skinny!
なければつくるのが OSS ということで
Scala on Rails なフレームワークを
作っています(2 週間前から)!
Scalatra + ScalikeJDBC + more...
http://git.io/skinny
ORM もあるよ
case class Developer(id: Long, groupId: Opion[Long],
group: Option[Group] = None, skills: Seq[Skill] = Nil)
object Developer extends SkinnyCRUDMapper[Developer] {
belongsTo[Group](Group, (d, g) => d.copy(group = g)).byDefault
hasManyThrough[Skill](DeveloperSkill, Skill, (d, skills) => d.coply(skills = skills))
def extract ...
}
Developer.findAll()
Developer.findById(123)
Developer.createWithAttributes(params.permit(“id”, “groupId”))
Developer.updateById(123).withAttributes(attrs)
Developer.deleteById(123)
Thanks
- 非同期 JDBC なんてなかったんやー
- ScalikeJDBC のご紹介
- ScalikeJDBC-Async のご紹介
- Skinny Framework のご紹介

歌舞伎座.tech 1 LT - ScalikeJDBC Async & Skinny Framework #kbkz_tech

  • 1.
    非同期 JDBC inScala @seratch Kazuhiro Sera
  • 2.
  • 3.
  • 4.
  • 5.
       ミ ヽヽヽリリノノノノ   彡ミイ  ̄ ̄'` ̄ヾミ    彡ミi )      ;|ミ    彡ミ〉 _,,,,,,,,, i,i ,,,,,_イミ  JDBC と言ったな、     rミi  _-・- l-・-、v     {6〈`┬  、_」_  イ   あれは嘘だ。    ヾ|  (  ,-ー-、) |     \ `- ͡-´ノ 、 '  ’     /i\ __ノ - ∩_____ ’    /\_  _ノ\   ( イ___ヨ - パッ   (_Y  ヽノ )イ͡ニ ,ノ     (  )____/ `ー-ー´    ー-',..-'ー.-,ー!..ー,,-._ー.,-ー.,-ー-...,,____    l         |   i       i   ''i,,_
  • 6.
    JDBC っぽい non-blocking なDB アクセス in Scala @seratch Kazuhiro Sera
  • 7.
    ScalikeJDBC  - Scala のDB アクセスライブラリ - “仕事で使っても詰まない” - SQL 書ける、柔軟性、拡張性、スピー ディなバグ対応・リリース、日本語 - Slick、Squeryl ほど有名じゃないけ ど、結構イケる感じです
  • 8.
    DSL で書いた例 import scalikejdbc._,SQLInterpolation._ val memberId = 123 val member = DB readOnly { implicit session => withSQL { select.from(Member as m) .where.eq(m.id, memberId).and.isNull(m.deletedAt) }.map(Member(m)).single.apply() }
  • 9.
    生 SQL も書けるよ importscalikejdbc._, SQLInterpolation._ val memberId = 123 val member = DB readOnly { implicit session => sql”””select id, name from member where id = ${memberId} and deleted_at is null””” .map(Member(m)).single.apply() }
  • 10.
    Get things done -わかりやすくて、ハマりにくい - 独自のノウハウを探しまわる必要なし - 1 人目のちゃんと使える人の確保が容易 (Scala の基本と SQL のみ) - Cookbook(日本語)販売中
  • 11.
    Productive - ほぼタイプセーフな APIを提供 - sbt プラグインでソースコード自動生成 - スロークエリ、Fluentd にも送れる - specs2、ScalaTest それぞれに AutoRollback サポート
  • 12.
  • 13.
    ScalikeJDBC-Async - ScalikeJDBC のAPI 互換だけど内部は JDBC じゃない - Activate という他のライブラリに触発 されて実装した(2013/7) - 国内外でのいくつか利用事例を認識して いますが、一応まだアルファバージョン
  • 14.
    How? - postgresql-async/mysql-async by @mauricioをラップした - Netty ベースの独自ドライバ - queue を持った ConnectionPool - Transaction は Connection を占有し て実現(begin/commit 自前で発行)
  • 15.
    ほぼそのまま! import scalikejdbc._, SQLInterpolation._,async._ val memberId = 123 val member = AsyncDB withPool { implicit session => withSQL { select.from(Member as m) .where.eq(m.id, memberId).and.isNull(m.deletedAt) }.map(Member(m)).single.future() }
  • 16.
    Tx は for式で val name = “Typesafe” val programmers = Seq(“Alice”, “Bob”, “Chris”) val resultFuture = AsyncDB localTx { implicit tx => for { company <- Company.create(name) employees <- company.hireAll(programmers) } yield () }
  • 17.
    Tips - Future[Option[_]] やFuture[List[_]] だらけになるので for 式で書くとよい - Play2 は Controller の Action に Future のまま渡せるのでやりやすい
  • 18.
    OMT? LT なのに Onemore thing 的なアレ。
  • 19.
    Really Must? 確かに JDBCがブロックして 困るアプリの開発もあるが そうじゃないものの方が多い というのが現実(リアル)では?
  • 20.
    Most cases? - うちのアプリ、実際Servlet + JDBC で 十分さばけてる(知ってた) - Reactive? C10K? 何それおいしいの? - 実は普通の管理画面作りたいだけ - Java は得意だけど今更の Java 感
  • 21.
    Rails?  実際、フロントエンドの合理的な選択。 私自身 Java でできたAPI サーバと Rails フロントエンドがメインのお仕事。 でも、今日ここにいる皆さんはきっと できれば Scala がいいんですよね・・
  • 22.
    Grails?  SI 業界な事情があるところ以外は 「だったらもう Railsで(ry」と思うけど ともあれ、今日ここにいる皆さんは Groovy より Scala ですよね・・
  • 23.
    Play2?  Play2 は発展途上 &Reactive 指向。 見た目から Play1/Rails 的なものを期待して ミスマッチになっていないか? 管理画面つくるの Play2 で本当に楽?
  • 24.
    Skinny! なければつくるのが OSS ということで Scalaon Rails なフレームワークを 作っています(2 週間前から)! Scalatra + ScalikeJDBC + more... http://git.io/skinny
  • 25.
    ORM もあるよ case classDeveloper(id: Long, groupId: Opion[Long], group: Option[Group] = None, skills: Seq[Skill] = Nil) object Developer extends SkinnyCRUDMapper[Developer] { belongsTo[Group](Group, (d, g) => d.copy(group = g)).byDefault hasManyThrough[Skill](DeveloperSkill, Skill, (d, skills) => d.coply(skills = skills)) def extract ... } Developer.findAll() Developer.findById(123) Developer.createWithAttributes(params.permit(“id”, “groupId”)) Developer.updateById(123).withAttributes(attrs) Developer.deleteById(123)
  • 26.
    Thanks - 非同期 JDBCなんてなかったんやー - ScalikeJDBC のご紹介 - ScalikeJDBC-Async のご紹介 - Skinny Framework のご紹介