狠狠撸

狠狠撸Share a Scribd company logo
1
厂濒颈肠办入门
Takako Shimamoto
BizReach, Inc.
2
アジェンダ
? Scalaの代表的なORM
? Slickの基本的なお話
– スキーマ定義
– クエリ
? SQLを直接書く方法
– Plain SQL
– その他の選択肢
? Play2 + Slickで使うには
– 設定
– コネクションまわり
? プロジェクトでの留意点
3
Scalaで使えるORM
? Slick(旧ScalaQuery)
– タイプセーフなDSLや、SQLも記述可能
– 極力Scalaのコレクションと同じように扱えるよう設計され
ている
? Squeryl
– SQLは使用せず、DSLでクエリを記述する
– コンセプトは、できるだけシンプルに
val query =
from(table)
(t => where(t.id === id) select(t))
4
Scalaで使えるORM
? Anorm
– SQLを直接書くスタイル
– 手動でORマッピングを行う
? Scala ActiveRecord
– Squerylをベースに、モデル定義やよく使う機能をRailsの
ActiveRecordに似せている(CoC、DRY)
SQL("select * from User")
.as( int("id") ~ str("name") map {
case id~name => Person(id, name)
} *)
5
他にも、Activate、ScalikeJDBC、SORM など???
本日はTypesafe社お墨付きの
Slickについてお話します
6
Slickのきほん
7
タイプセーフなクエリ
? Slickは以下のように、クエリをタイプセーフに記述で
きることが1つの特徴
? このクエリを書くためには、スキーマ定義が必要
val id = 1L
val user: Option[UsersRow] =
Users.filter(_.id is id.bind).firstOption
select * from USERS x1 where x1.ID = ?
SQLのイメージ
8
スキーマ定義
? でも、手動で書くのは面倒ですよね
// マッピングするケースクラス
case class UserRow(id: Long, name: String)
// テーブルのスキーマ定義
class User(tag: Tag) extends Table[UserRow](tag, "USER") {
def * = (id, name) <> (UserRow.tupled, UserRow.unapply)
val id: Column[Long] = column[Long]("ID", O.PrimaryKey)
val name: Column[String] = column[String]("NAME")
}
// クエリに使用
lazy val User = new TableQuery(tag => new User(tag))
9
実はジェネレータがあるんですよ
10
コードジェネレータ
? sbtのタスクとして実行
? 生成するファイル
– Tables.scala
? 生成されるもの
– テーブル定義
– マッピングするケースクラス
– TableQuery
? クエリで使用
– 全テーブルのDDL
– GetResult(ResultSetからケースクラスに変換)
? Plain SQLで使用
11
コードジェネレータ
? ジェネレータはカスタマイズ可能
– SourceCodeGeneratorを拡張する形
– ドキュメントがないので拡張ポイントがわかりにくい
– slick.model.codegenパッケージ配下を見るとよい
? BizReachではカスタマイズして使っている
– 基本的なCRUD機能
– シールドクラスとカラムのマッピング
– 楽観的排他による更新機能
12
これでクエリが書けます
13
基本的なCRUD
// 全件取得
val users: Seq[UserRow] = User.list
// 登録
val res: Int = User insert UserRow(1, "なまえ")
// 更新
val res: Int = User.filter(_.id is id.bind).update(
UserRow(1, "なまえ変更"))
// 削除
val res: Int = User.filter(_.id is id.bind).delete
14
基本的なCRUD
// 全件取得
val users: Seq[UserRow] = User.list
// 登録
val res: Int = User insert UserRow(1, "なまえ")
// 更新
val res: Int = User.filter(_.id is id.bind).update(
UserRow(1, "なまえ変更"))
// 削除
val res: Int = User.filter(_.id is id.bind).delete
bindを呼ぶと
バインド変数になる
15
バインド変数になるbind
? bindなし
? bindあり
val name = "ta'kako"
User.filter(_.name is name).firstOption
??? from USER x1 where x1.NAME = 'ta''kako'
SQLのイメージ
User.filter(_.name is name.bind).firstOption
??? from USER x1 where x1.NAME = ?
SQLのイメージ
16
ケースクラスにマッピング
? <>を使えば、mapで絞り込んだ項目を別のケースク
ラスにマッピングできる
// このケースクラスにマッピング
case class Test(id: Long, name: String)
val res: List[Test] = User.map { t =>
t.id -> t.name <> (Test.tupled, Test.unapply)
}.list
17
他にもいろいろ
? ソート、グルーピング、ページング など
? 内部結合、外部結合も可能
? slick-referenceをGitHubに公開中
https://github.com/bizreach/slick-reference
18
タイプセーフなクエリで書けない
ときは?
19
Plain SQL
? SQLを文字列リテラルで書く
? 局所的に使うには便利
? ただ、複雑なSQLの代替として使うには厳しい
– リファクタリングがやりにくい
– 動的なSQLを組み立てるためには文字列処理が必要
sql"""SELECT ID + 1
FROM ISSUE_ID
WHERE USER_NAME = $owner FOR UPDATE
""".as[Int].firstOption
20
その他の選択肢
? mirage-scala
– Seasar2の2WaySQLの機能を単独のライブラリとして利
用できるようにしたもの
– Slickと組み合わせて使用することも可能
val books: List[Book] = sqlManager.getResultList[Book](
Sql("""
SELECT BOOK_ID, BOOK_NAME, AUTHOR, PRICE
FROM BOOK
/*IF author!=null*/
WHERE AUTHOR = /*author*/'test'
/*END*/
"""), Map("author"->"Takako Shimamoto"))
パラメータはMapではなくケース
クラスで与えることも可能
条件分岐やパラメータをSQLのコメント
で記述するのでコピペしてそのままDB
に流して動作確認できる
外部ファイル化することも可能
21
Play2でSlickを使うには
22
play-slick
? Play2でSlickを使う上で、面倒なことをいろいろやっ
てくれるプラグイン
– Play2の設定から自動的にSlickの
Database.forDataSourceを呼び出してくれる
– Slickのセッション管理を自動的にやってくれる
? withSessionやwithTransactionを呼び出してくれる
– Play2のリクエストとSlickのセッションの両方を持ち合わ
せたDBSessionRequestが使える
SlickがPlay2に組み込まれるのと同時に
このプラグインも統合される予定
23
何が変わるの?
? コントローラでPlay2のActionの代わりに、play-slick
のDBActionを使う
? トランザクションを開始する場合は
DBAction.transactionを使う
def list = DBAction { implicit rs =>
// IDの昇順にすべてのユーザ情報を取得
val users = Users.sortBy(t => t.id).list
// 一覧画面を表示
Ok(views.html.user.list(users))
}
24
コネクションプール
? Slickはコネクションプールの実装を持っていない
? Play2と組み合わせて使うならBoneCP
? ただし、有名なリーク問題が未だにある
– https://bugs.launchpad.net/bonecp/+bug/999114
? 対処方法は
– BoneCPのバージョンを固定
– maxConnectionAgeを0にする
? 現在は、HikariCPをお試し中
25
プロジェクトで使う上で注意
することは?
26
留意事項
? アグレッシブな機能追加/削除
– Scala全体の傾向(Slickも例外ではない)
– 特にメジャーアップにはマイグレーションが必要
– 常にキャッチアップして対応していく必要がある
? マニュアルがあまり豊富でない
– 本家サイトには書いてないが、できることが色々ある
– 慣れるまでに多少の時間が必要
– 充実させようとしている動きはある
– BizReachで公開しているリファレンスをぜひ活用を
27
留意事項
? 結合は発行されるSQLに注意
– 単一テーブルなら、①fiterで絞り込む、②mapで取得項目
を決める、③listやfirstOptionで実行、という流れ
– 結合は、メソッドチェーンとfor式で発行するSQLが異なる
// select ??? from (select * from A) s1 inner join (select * from B) s2
on ???
A.innerJoin(B).on(???)
// select ??? from A s1, B s2 where (s1.column = s2.column) and ??
for {
t1 <- A
t2 <- B
if ???
} yield ???
28
留意事項
? Play2のEvolutionsは実践には厳しい
– 1.sql、2.sql???の管理はプログラマがやる
– ミスした場合、エボリューション用のテーブルを元に戻すと
いう操作を手動でやらないといけない
– ある程度の規模になるとメンテが困難
29
Slickの今後
30
次期バージョン2.1
? 使いやすさの向上
– APIの改善
– ドキュメントの充実
? Play2.4からデフォルトのO/Rマッパ(予定)
? Direct Embedding
– ケースクラスにアノテーションを付与
? スキーマ定義が不要になる
– 暗黙の型変換の代わりに、マクロを使用
? 実装するコード量が減る
– 現在は実験的な機能として提供
? 今後に期待
Ad

Recommended

Multithreading in java
Multithreading in java
junnubabu
?
Packages in java
Packages in java
Jerlin Sundari
?
Flyweight pattern
Flyweight pattern
Shakil Ahmed
?
Proxy Design Pattern
Proxy Design Pattern
Anjan Kumar Bollam
?
Reflection in C Sharp
Reflection in C Sharp
Harman Bajwa
?
Polymorphism
Polymorphism
Raffaele Doti
?
Observer Software Design Pattern
Observer Software Design Pattern
Nirthika Rajendran
?
C# Types of classes
C# Types of classes
Prem Kumar Badri
?
めんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scala
Kazuhiro Sera
?
[Japanese] Skinny Framework で始める Scala #jjug_ccc #ccc_r24
[Japanese] Skinny Framework で始める Scala #jjug_ccc #ccc_r24
Kazuhiro Sera
?
Getting started MySQL as Document Data Store
Getting started MySQL as Document Data Store
Chihiro Ito
?
【修正版】Django + SQLAlchemy: シンプルWay
【修正版】Django + SQLAlchemy: シンプルWay
Takayuki Shimizukawa
?
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
Kent Ohashi
?
SQLQL は GraphQL にとってなんなのか
SQLQL は GraphQL にとってなんなのか
yancya
?
骋谤辞辞惫测で楽に厂蚕尝を実行してみよう
骋谤辞辞惫测で楽に厂蚕尝を実行してみよう
Akira Shimosako
?
翱/搁マッパーによるトラブルを未然に防ぐ
翱/搁マッパーによるトラブルを未然に防ぐ
kwatch
?
公司における厂辫谤颈苍驳蔼日本蝉辫谤颈苍驳ユーザー会20090624
公司における厂辫谤颈苍驳蔼日本蝉辫谤颈苍驳ユーザー会20090624
Yusuke Suzuki
?
金魚本読書ノート JPA編
金魚本読書ノート JPA編
Kazuyoshi Kamitsukasa
?
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon
Kazuhiro Sera
?
イマドキの现场で使える闯补惫补ライブラリ事情
イマドキの现场で使える闯补惫补ライブラリ事情
takezoe
?
既存システムへの新技術活用法 ~fluntd/MongoDB~
既存システムへの新技術活用法 ~fluntd/MongoDB~
じゅん なかざ
?
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
Tsuyoshi Yamamoto
?
フリーでできるセキュリティ奥别产编(厂蚕尝惭あpを楽しもう)
フリーでできるセキュリティ奥别产编(厂蚕尝惭あpを楽しもう)
abend_cve_9999_0001
?
Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4
Ransui Iso
?
社会ネットワーク分析第7回
社会ネットワーク分析第7回
Satoru Mikami
?
Tour of Apache PredictionIO in 10 Minutes
Tour of Apache PredictionIO in 10 Minutes
chibochibo
?
Crawler Commons
Crawler Commons
chibochibo
?

More Related Content

Similar to 厂濒颈肠办入门 (20)

めんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scala
Kazuhiro Sera
?
[Japanese] Skinny Framework で始める Scala #jjug_ccc #ccc_r24
[Japanese] Skinny Framework で始める Scala #jjug_ccc #ccc_r24
Kazuhiro Sera
?
Getting started MySQL as Document Data Store
Getting started MySQL as Document Data Store
Chihiro Ito
?
【修正版】Django + SQLAlchemy: シンプルWay
【修正版】Django + SQLAlchemy: シンプルWay
Takayuki Shimizukawa
?
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
Kent Ohashi
?
SQLQL は GraphQL にとってなんなのか
SQLQL は GraphQL にとってなんなのか
yancya
?
骋谤辞辞惫测で楽に厂蚕尝を実行してみよう
骋谤辞辞惫测で楽に厂蚕尝を実行してみよう
Akira Shimosako
?
翱/搁マッパーによるトラブルを未然に防ぐ
翱/搁マッパーによるトラブルを未然に防ぐ
kwatch
?
公司における厂辫谤颈苍驳蔼日本蝉辫谤颈苍驳ユーザー会20090624
公司における厂辫谤颈苍驳蔼日本蝉辫谤颈苍驳ユーザー会20090624
Yusuke Suzuki
?
金魚本読書ノート JPA編
金魚本読書ノート JPA編
Kazuyoshi Kamitsukasa
?
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon
Kazuhiro Sera
?
イマドキの现场で使える闯补惫补ライブラリ事情
イマドキの现场で使える闯补惫补ライブラリ事情
takezoe
?
既存システムへの新技術活用法 ~fluntd/MongoDB~
既存システムへの新技術活用法 ~fluntd/MongoDB~
じゅん なかざ
?
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
Tsuyoshi Yamamoto
?
フリーでできるセキュリティ奥别产编(厂蚕尝惭あpを楽しもう)
フリーでできるセキュリティ奥别产编(厂蚕尝惭あpを楽しもう)
abend_cve_9999_0001
?
Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4
Ransui Iso
?
社会ネットワーク分析第7回
社会ネットワーク分析第7回
Satoru Mikami
?
めんどくさくない Scala #kwkni_scala
めんどくさくない Scala #kwkni_scala
Kazuhiro Sera
?
[Japanese] Skinny Framework で始める Scala #jjug_ccc #ccc_r24
[Japanese] Skinny Framework で始める Scala #jjug_ccc #ccc_r24
Kazuhiro Sera
?
Getting started MySQL as Document Data Store
Getting started MySQL as Document Data Store
Chihiro Ito
?
【修正版】Django + SQLAlchemy: シンプルWay
【修正版】Django + SQLAlchemy: シンプルWay
Takayuki Shimizukawa
?
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
Kent Ohashi
?
SQLQL は GraphQL にとってなんなのか
SQLQL は GraphQL にとってなんなのか
yancya
?
骋谤辞辞惫测で楽に厂蚕尝を実行してみよう
骋谤辞辞惫测で楽に厂蚕尝を実行してみよう
Akira Shimosako
?
翱/搁マッパーによるトラブルを未然に防ぐ
翱/搁マッパーによるトラブルを未然に防ぐ
kwatch
?
公司における厂辫谤颈苍驳蔼日本蝉辫谤颈苍驳ユーザー会20090624
公司における厂辫谤颈苍驳蔼日本蝉辫谤颈苍驳ユーザー会20090624
Yusuke Suzuki
?
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon
Kazuhiro Sera
?
イマドキの现场で使える闯补惫补ライブラリ事情
イマドキの现场で使える闯补惫补ライブラリ事情
takezoe
?
既存システムへの新技術活用法 ~fluntd/MongoDB~
既存システムへの新技術活用法 ~fluntd/MongoDB~
じゅん なかざ
?
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
Grails-1.1を斬る!~Grails-1.1からのチーム開発~ in Tokyo
Tsuyoshi Yamamoto
?
フリーでできるセキュリティ奥别产编(厂蚕尝惭あpを楽しもう)
フリーでできるセキュリティ奥别产编(厂蚕尝惭あpを楽しもう)
abend_cve_9999_0001
?
Lisp Tutorial for Pythonista : Day 4
Lisp Tutorial for Pythonista : Day 4
Ransui Iso
?
社会ネットワーク分析第7回
社会ネットワーク分析第7回
Satoru Mikami
?

More from chibochibo (14)

Tour of Apache PredictionIO in 10 Minutes
Tour of Apache PredictionIO in 10 Minutes
chibochibo
?
Crawler Commons
Crawler Commons
chibochibo
?
LocalStack
LocalStack
chibochibo
?
Deadly Code! (seriously) Blocking &amp; Hyper Context Switching Pattern
Deadly Code! (seriously) Blocking &amp; Hyper Context Switching Pattern
chibochibo
?
Dynamic SQL in doobie
Dynamic SQL in doobie
chibochibo
?
Is spark streaming based on reactive streams?
Is spark streaming based on reactive streams?
chibochibo
?
What is doobie? - database access for scala -
What is doobie? - database access for scala -
chibochibo
?
蚕耻补谤迟锄て?肠谤辞苍を范囲検索したい
蚕耻补谤迟锄て?肠谤辞苍を范囲検索したい
chibochibo
?
ビッグじゃなくても使えるSpark Streaming
ビッグじゃなくても使えるSpark Streaming
chibochibo
?
苍颈辞で作った叠耻蹿蹿别谤别诲奥谤颈迟别谤に変えたら例外になった
苍颈辞で作った叠耻蹿蹿别谤别诲奥谤颈迟别谤に変えたら例外になった
chibochibo
?
Spark Streaming on AWS -S3からKinesisへ-
Spark Streaming on AWS -S3からKinesisへ-
chibochibo
?
Spark in small or middle scale data processing with Elasticsearch
Spark in small or middle scale data processing with Elasticsearch
chibochibo
?
What's a macro?: Learning by Examples
What's a macro?: Learning by Examples
chibochibo
?
Spring Boot Introduction
Spring Boot Introduction
chibochibo
?
Tour of Apache PredictionIO in 10 Minutes
Tour of Apache PredictionIO in 10 Minutes
chibochibo
?
Deadly Code! (seriously) Blocking &amp; Hyper Context Switching Pattern
Deadly Code! (seriously) Blocking &amp; Hyper Context Switching Pattern
chibochibo
?
Dynamic SQL in doobie
Dynamic SQL in doobie
chibochibo
?
Is spark streaming based on reactive streams?
Is spark streaming based on reactive streams?
chibochibo
?
What is doobie? - database access for scala -
What is doobie? - database access for scala -
chibochibo
?
蚕耻补谤迟锄て?肠谤辞苍を范囲検索したい
蚕耻补谤迟锄て?肠谤辞苍を范囲検索したい
chibochibo
?
ビッグじゃなくても使えるSpark Streaming
ビッグじゃなくても使えるSpark Streaming
chibochibo
?
苍颈辞で作った叠耻蹿蹿别谤别诲奥谤颈迟别谤に変えたら例外になった
苍颈辞で作った叠耻蹿蹿别谤别诲奥谤颈迟别谤に変えたら例外になった
chibochibo
?
Spark Streaming on AWS -S3からKinesisへ-
Spark Streaming on AWS -S3からKinesisへ-
chibochibo
?
Spark in small or middle scale data processing with Elasticsearch
Spark in small or middle scale data processing with Elasticsearch
chibochibo
?
What's a macro?: Learning by Examples
What's a macro?: Learning by Examples
chibochibo
?
Spring Boot Introduction
Spring Boot Introduction
chibochibo
?
Ad

厂濒颈肠办入门