MySQLとspecsのライブラリをsbtに登録しておく。
import sbt._
class MyProject(info: ProjectInfo) extends DefaultWebProject(info)
{
val lift = "net.liftweb" % "lift-core" % "1.1-M6" % "compile"
val jetty6 = "org.mortbay.jetty" % "jetty" % "6.1.19" % "test"
val servlet = "javax.servlet" % "servlet-api" % "2.5" % "provided"
val mysql = "mysql" % "mysql-connector-java" % "5.1.6" % "runtime"
val junit = "junit" % "junit" % "4.5" % "test"
val specs = "org.scala-tools.testing" % "specs" % "1.6.0" % "test"
val smackRepo = "m2-repository-smack" at "http://maven.reucon.com/public"
}
書き換えたら、必要なjarをかき集めておきます。
C\myproject>sbt update
Lift1.0のDB設定
こんな感じでConnectionManagerを書いていました。
■/src/main/scala/bootstrap/liftweb/Boot.scala
DB.defineConnectionManager(DefaultConnectionIdentifier, MySQLVendor)
object MySQLVendor extends ConnectionManager {
def newConnection(name: ConnectionIdentifier): Box[Connection] = {
try {
Class.forName("com.mysql.jdbc.Driver")
val dm = DriverManager.getConnection("jdbc:mysql://localhost/db?user=xxx&password=xxx")
Full(dm)
} catch {
case e : Exception => e.printStackTrace; Empty
}
}
def releaseConnection(conn: Connection) {conn.close}
}
Lift1.1の場合は、propertiesファイルで指定する流儀
■/src/main/resources/default.props
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost/db
db.user=xxxxx
db.password=xxxxx
プロパティファイルの名称は、環境で切り替えられるようになっていて、
運用モード[run.mode=production] → production.default.props
テストモード[run.mode=test] → test.default.props
開発モード[run.mode=_] → default.props
などで切り替えます。run.modeは、JVM環境変数(-Drun.mode=testなど)です。
指定しなければ、開発モードでdefaults.propsを参照します。
その他、OSユーザー毎、マシン毎にプロパティファイルを書き換えることができます。net.liftweb.util.PropsのAPIリファレンスを参照。ちなみにDB以外の情報でも使えます。
モデル作ってspecs実行まで
■/src/main/scala/myproject/model/Product.scala
package myproject.model
import _root_.net.liftweb.mapper._
import _root_.net.liftweb.util._
class Product extends LongKeyedMapper[Product] with IdPK {
def getSingleton = Product
object name extends MappedString(this, 255)
}
object Product extends Product with LongKeyedMetaMapper[Product]{
override def dbTableName = "products"
def findByName(name:String) = findAll(By(Product.name,name))
}
を作ったら、Bootstrapでboot時にテーブルスキーマを生成するように登録しておきます。
val models = List( User, Product )
Schemifier.schemify(true, Log.infoF _, models:_* )
■/src/test/scala/myproject/model/ProductTest.scala
package myproject.model
import org.specs._
import org.specs.matcher._
import org.specs.specification._
object ProductTestSpecs extends Specification {
"Product" should {
"be available" in {
(new bootstrap.liftweb.Boot).boot
Product.count must notBeNull
}
}
}
実行すると、bootを呼んだときに、Productに対応するテーブルをCREATEしてくれます。
C\myproject> sbt
> test
[info] == myproject.model.ProductTestSpecs ==
INFO - CREATE TABLE products (id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE KEY ,name VARCHAR(255)) ENGINE = InnoDB
[info] == test-finish ==
[info] Run: 1, Passed: 1, Errors: 0, Failed: 0
[info] All tests PASSED.
[success] Successful.
[info] Total time: 4 s
さすがにexample毎にbootするのはアレなので、specsフレームワークのもっと上位のフックで準備しておけばよいでしょう。
LiftConsoleの使い方
C:\myproject> mvn scala:console -DmainConsole=LiftConsole
scala> import myproject.model._
scala> Product.create.name("scala gum").save
scala> Product.findAll
などと、コンソール上でモジュールの動作を確認できます。
※今日教えていただいたScalaTohoku、yuroyoroさん、ありがとうございました!
Railsなどでお馴染みの機能はだいたいそろってますね。