##その前に
Play framework 2.x Scala Advent Calendar 2013
の3日めのエントリになります。
Scala + Playを勉強し初めて半年ちょっとの@ryu1_okdです。よろしくどうぞ。
##Slickの書き方まとめ
全体的にSlickの書き方をまとめる予定でしたが、
書いてる間に4日に突入してしまったので自分がSlickを使ってる中で詰まった箇所を書いておこうかと思います。
※Slickのバージョンは1.0.1です。DBはMariaDB
COUNT文
意外とハマりました。。
count は deprecatedになっているし、Query.lengthじゃないと使えないとか聞いてないしー。
Query(Class.length).first()
Query(Class.where(_.id === id).length).first()
###動的にWhere句の生成
みんなどうやってるんだろ?とりあえず queryを varで定義してパラメータを判定してWhereをチェインしていく感じで突破した。
Option型の使い方とかこれが正解とは思ってないです。
case class SearchForm(title:Option[String],startDate:Option[DateTime],endDate[DateTime])
def findBySearchForm(form:SearchForm) = db.withSession{
var query = for( c <- Class) yield c
if( form.title.nonEmpty ) query = query.where(_.title like "%" + form.title.get + "%")
if(form.startDate.nonEmpty) query = query.where(_.startTime >= (new Timestamp(form.startDate.get.getMillis)))
if(form.endDate.nonEmpty) {
val endTime = form.endDate.get.plusDays(1) // 1日進ませる
query = query.where(_.endTime < (new Timestamp(endTime.getMillis)))
}
}
group by + join
select * , (select count(*) from B where B.aId=A.id) , (select count(*) form C where C.aId=A.id) from A , D, E where A.dId=D.id and A.eId=E.id
みたいな感じのSQLを書きたい場合 まぁなかなか無いでしょうが。。
val query = for{
((a,bb),cc) <- A leftJoin(for((id,bb) <- B.groupBy(_.aid)) yield (aId,bb.length)) on(_.id === _._1) leftJoin (for((aId,cc) <- C.groupBy(_.aId)) yield (aId,cc.length)) on(_._1.id === _._1)
d <- D
e <- E
if(a.dId === d.id && a.eId === e.id)
} yield (a,d,e, bb._2.ifNull(0), cc._2.ifNull(0))
と書きました。 とりあえず目的の結果が得られたからよしとしていますが、
PlainSQLでやったほうがいいんだろうか・・・
関数呼び出し
SimpleFunctionを使用するのですが、これはTypesafeのSlideShareで見つけてたので使いたかったという感じで、たまたまランダムで3件取得するようなパターンがあったので使ってみました。
MariaDB(MySQL)なのでRANDというランダム関数を使います。
private def random = SimpleFunction[Long]("RAND").apply(Seq())
def findRandomThree = db.withSession{
Query(Class).sortBy(_.random).take(3).list()
}
おわり
人生初のAdventCalendarに参加しました。自分の目標である「発信する側になる」というのに一歩でも近づけたのではないでしょうか。
ただ、Play framework 2.x Scala Advent Calendar 2013 参加者少ないし、そもそも成立してない可能性が・・・
まだまだ空きはありますので、ぜひ参加してください。
Scalaのほうはまだまだ勉強不足を実感する毎日ですね。
仕事ではPlay2 + Scala + Slick で頑張ってますが、個人的にはScalikeJDBCをやってみようと動いてます。
そのあとskinnyに手を出す予定。いや先skinnyのほうが入りやすいんでしょうか。
というわけで明日は勝手に大尊敬しておりますskinny ScalikeJDBC作者の@seratchさんです。
このAdventCalenderが動いていることを信じて楽しみにしてます。