ORMを使う - Squeryl
最近Scala勉強してます。
仕事ではここ半年以上ずっと、Railsなので、
ScalaではPlayを使ってみようと思い、始めました。
ただ、ことDBアクセスに関してはPlay標準のAnormは、なんかしっくりこない、、、
ActiveRecord的な感覚で使えるORMは無いものか、と。
色々探した結果、「Squeryl」を使う事にしました。
※読み方がわかりません。ご存知の方教えてください。すくえりる?すくーりる?すくいれる?
以下、Play上でSquerylを使えるようにする手順です。
※今回はこちらを参考にさせて頂きました : Play 2.0 & squeryl simple integration
■環境
OS: MacOSX 10.7.3
Scala : 2.9.1
Play: 2.0
Squeryl: 0.9.5
1.sbt使ってるので、sbtでquerylを入れる
project/Build.scalaに以下のように追記(DBはMySQLを使います)
import sbt._ import Keys._ import PlayProject._ object ApplicationBuild extends Build { val appName = "play_sample" val appVersion = "1.0-SNAPSHOT" val appDependencies = Seq( "org.squeryl" %% "squeryl" % "0.9.5", "mysql" % "mysql-connector-java" % "5.1.18" ) val main = PlayProject(appName, appVersion, appDependencies, mainLang = SCALA).settings( // Add your own project settings here ) }
※IntelliJIDEAを使っている場合は、ここでplayコンソールから
update idea
を実行する。
2.GlobalSettingsのonStartでゴニョる
import play.api._ import play.api.db._ import org.squeryl.{Session, SessionFactory} import org.squeryl.adapters.MySQLAdapter object Global extends GlobalSettings { override def onStart(app: Application) { SessionFactory.concreteFactory = Some( () => connection ) def connection() = { Session.create(DB.getConnection()(app), new MySQLAdapter) } } }
アダプターはその他にも
- DB2Adapter
- DerbyAdapter
- H2Adapter
- MySQLAdapter
- MySQLInnoDBAdapter
- OracleAdapter
- PostgreSqlAdapter
があるようです。
たしか、MySQL5.5からInnoDBがデフォルトになったんでしたっけ?
だとすると、MySQLInnoDBAdapterを使うべきかも、、、
3.モデルクラス作成
app/models/User.scala
package models case class User(var name: String, var email: String, var password: String) extends BaseEntity { def this() = this("", "", "") }
app/models/Schema.scala
package models import org.squeryl.KeyedEntity class BaseEntity extends KeyedEntity[Long] { val id: Long = 0 }
4.Repository的なオブジェクトを作成
app/models/Schema.scala
... import org.squeryl.Schema object CoreSchema extends Schema { val users = table[User]("user") on(users)(ent => declare( ent.id is(autoIncremented), ent.email is(unique, dbType("varchar(255)")) )) }
以上、で準備完了です。
実際に使ってみます。
... def submitEntry = Action {implicit request => userForm.bindFromRequest.fold( errors => BadRequest(views.html.entry(errors)), user => { inTransaction { CoreSchema.users.insert(user) Redirect(routes.UserController.showEntry(user.id)) } } ) } def showEntry(id: Long) = Action {implicit request => inTransaction { val user = CoreSchema.users.where(u => u.id === id).single Ok(views.html.result(user)) } }
基本的に、inTransactionのブロック内でアクセスします。(もしくはtransaction)(これらのメソッドはエイリアス的な感じになってるのかな??)
(そうしないと怒られました)
必ずトランザクション張るんでしょうか?
selectのみでもinTransactionというのは非常に違和感がありますね。
- inTranscationとtranscationは全く同じなのか
- 必ずトランザクションを張らないとイケないのか?(更新系の処理時のみになっているのか)
などは、これから要調査です。
よし、次はAjaxやってみて、その次はPjaxのサンプルを作ってみることにします。