Slick+PlayFramework2.1でDBアクセスしjsonで出力

実際の業務では、サンプルなどでよく見かける、データの作成、更新、参照、削除という流れは実際ではあまりなく、既にあるデータを参照するだけとか祖いうのが多いかと思います。

前回までで、既存データベースに入っているデータを取得することができたので、JSON形式で出力してみます。

GSON

sjsonやPlay標準のJSONなど何種類かあるようですが、ちょっと試したところうまくいかなかったので、GSONを使用することにしました。

あらかじめGSONをダウンロードしておきeclipseのパスに追加しておきます。

http://code.google.com/p/google-gson/

mysql

use data
;
create table price(
code varchar(10) not null,
date datetime not null,
open int ,
high int,
low int,
close int
)
;
create unique index price1 on price(code,date)
;

application.conf

db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://localhost/data"
db.default.user=root
db.default.password=
slick.default="models.*"
evolutionplugin=disabled

routes

GET /data/price/:code	controllers.Data.OHLC(code:String)

controllers.Data.scala

package controllers
import play.api._
import play.api.mvc._
import models._
import com.google.gson._

object Data extends Controller {
	val gson:Gson=new GsonBuilder().setDateFormat("yyyy-MM-dd").create // 日付のフォーマットをしておく
	def OHLC(code:String)=Action {
		Ok(views.html.json(gson.toJson(Prices.select(code))))
	}
}

models.Price.scala

package models
import scala.slick.driver.H2Driver.simple._
import Database.threadLocalSession

import play.api.db._
import play.api.Play._

import scala.slick.jdbc.{GetResult, StaticQuery => Q}
import Q.interpolation

case class Price(code:String,date:java.sql.Date,open:Int,high:Int,low:Int,close:Int) extends Ordered[Price]{
	def compare(that:Price):Int={
		date.getTime().compare(that.date.getTime())
	}
}

object Prices extends Table[Price]("price") {
	val DATE_TERM=180 // 180日分とる
	
	def code=column[String]("code",O.PrimaryKey)
	def date=column[java.sql.Date]("date",O.PrimaryKey)
	def open=column[Int]("open")
	def high=column[Int]("high")
	def low=column[Int]("low")
	def close=column[Int]("close")
	def * = code ~ date ~ open ~ high ~ low ~ close <> (Price,Price.unapply _)

	implicit val getPrice=GetResult(rs=>Price(rs<<,rs<<,rs<<,rs<<,rs<<,rs<<))
	
	def select(code:String)= connectDB{
		val list=sql"select * from price where code=$code order by date desc limit $DATE_TERM".as[PriceHistAdj].list.sorted
		// sort 逆順なので並べ替える、GSON用にArrayList化
		val ary=new java.util.ArrayList[Price]
		for(l<-list)ary.add(l)
		ary
	}
	def connectDB[Any](f: => Any): Any = {
		Database.forDataSource(DB.getDataSource("data")) withSession {
			f
		}
	}
}

views.json.scala.html

jsonp用

@(json:String)
callback(@json);