Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
13
Help us understand the problem. What is going on with this article?
@ryu1_okd

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

13
Help us understand the problem. What is going on with this article?
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
ryu1_okd

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
13
Help us understand the problem. What is going on with this article?