Posted at

Slick 詰まって頑張った

More than 5 years have passed since last update.


その前に

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が動いていることを信じて楽しみにしてます。