14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Slick 詰まって頑張った

Posted at

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

14
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?