Help us understand the problem. What is going on with this article?

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

ryu1_okd
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした