scalaのWebフレームワーク liftで遊ぶ(8) - いよいよModelでCRUDするぜ?
目次はこちら。
scalaのWebフレームワーク liftで遊ぶ 目次 - ゆろよろ日記
こんばんは、土井善晴です。
今日はね。Modelをやりますよー。
最近のフレームワークとおんなじでね、Liftでも簡単にCRUDが作れるんですよー。
ではやってみましょうかね。
LiftでのORM
LiftでのORMの特徴はこんな感じ。
- テーブル操作を行うMetaMapperとモデルクラスを定義するKeyedMapperを作成すれば利用可能。
- 定義とMigrationが一元化されている。モデルクラスを定義すると、アプリケーション起動時に自動的にテーブルが作成・更新される。
- CRUD操作メソッドやfinderメソッドは自動的に追加される。RailsのAR的なアプローチ
- モデルクラスに、formタグやtableタグなどのHTMLを出力するメソッドがある。
じゃじゃじゃじゃじゃじゃじゃあじゃあじゃあ、動かしてみますよ。
モデル作り
mavenでプロジェクトを作成する。
CRUDの動作確認用のプロジェクトを作りますよ。
mvn archetype:create -U -DarchetypeGroupId=net.liftweb -DarchetypeArtifactId=lift-archetype-basic -DarchetypeVersion=0.9 -DremoteRepositories=http://scala-tools.org/repo-releases -DgroupId=com.yuroyoro -DartifactId=lift-model
基本的なDBへのマッピング
net.liftweb.mapperパッケージはDBへのマッピングを提供する。
liftでモデルを作るには、こんな感じになる。
package com.yuroyoro.model import net.liftweb.mapper._ object Entry extends Entry with KeyedMetaMapper[Long,Entry]{ override def dbTableName = "entries" override def fieldOrder = id :: title :: entry :: Nil } class Entry extends KeyedMapper[Long,Entry]{ def getSingleton = Entry // Metaオブジェクト def primaryKeyField = id // 主キーの設定 object id extends MappedLongIndex(this) object title extends MappedString(this,300) object entry extends MappedString(this,8192) }
ソースの説明。
- net.liftweb.mapper.KeydMapperを継承したclassを定義する。
- モデルオブジェクト
- KeyedMappaerには、主キーの型と自信のクラスを型パラメータとして与える
- getSingletonで、2のMetadataオブジェクトを取得できるようにする
- primaryKeyFieldに主キーとなるフィールドを設定する
- フィールドを定義する。(object id extends MappedLongIndex(this))
- 1を継承して、net.liftweb.mapper.KeyedMetaMapperというtraitをwithで実装したObjectを用意する。
- KeyedMetaMapper : データベース操作(Create,Finderなど)が定義されているtrait。
- マッピングするテーブル名を定義する。(override def dbTableName = "entries" )
- MappedField:フィールドの属性をあらわすクラス。
- MappdedString,MappedLongなど各種の型に対応したクラスがある。
- フィールドの並び順をListで定義する。(override def fieldOrder = id :: entry :: Nil )
このようにすると、基本的なCRUD操作のメソッドが利用できる。(表の中のAはModelの型。)
create: A | Modelオブジェクトを生成する。 |
find(by: QueryParam[A]*): Can[A] | 1レコードを対象としたfinderメソッド。引数にQueryParamを渡すことで検索条件を指定できる。 |
findAll: List[A] | 全件検索用のfinderメソッド。 |
findAll(by: QueryParam[A]*): List[A] | 検索条件を指定したfinderメソッド。条件にあったレコードをすべてListで返す。 |
save(toSave: A): Boolean | 引数のModelオブジェクトの状態をDBに保存する。成功したかがBooleanで返される。 |
検索条件を指定するQueryParamクラスは、以下のようなcaseクラスを継承している。
Cmp[O | 比較を行う条件。フィールド、比較のオペレータ(OprEnum.Eqlなど),比較対象の値,他のフィールドの順で指定する。Cmp(title,OprEnum.Eq,"ほげほげ",Empty)など |
OrderBy[O | Order Byを指定する。 |
ByList[O | INを指定する。フィールド名と、値のListを渡す。実際のSQLはORで連結。 |
BySql[O | SQLを直接指定する。queryには、PreparedStatementのようにプレースホルダを含むことができ、paramsにパラメータを設定できる。 |
MaxRows[O | 取得件数を指定する。 |
StartAt[O | 検索対象のレコードから開始位置を指定する。 |
1から10件目のレコードを取得するには、こんな感じにすればよい。
Entry.findAll(StartAt(0), MaxRows(10))
Cmpクラスを利用して検索条件を指定しても良いが、以下のObjectでもっと簡単に条件を指定できる。
By | 指定したフィールド名で、一致する値のレコードを検索する。By(title,"hogehoge")だとtitle='hogehoge'となる。 |
NotBy | 指定したフィールド名で、一致しない値のレコードを検索する。NotBy(title,"hogehoge")だとtitle<>'hogehoge'となる。 |
ByRef | 指定したフィールド名で、もう一方のフィールド名と一致する値のレコードを検索する。ByRef(title,id)だとtitle=idとなる。 |
NotByRef | 指定したフィールド名で、もう一方のフィールド名と一致しない値のレコードを検索する。NotByRef(title,id)だとtitle<>idとなる。 |
By_> | 指定したフィールド名で、引数の値より大きい値を持つレコードを検索する。比較する値には、他のフィールド名も指定できる。By_>(id,5)だとid>5となる。 |
By_< | 指定したフィールド名で、引数の値より小さい値を持つレコードを検索する。比較する値には、他のフィールド名も指定できる。By_<(id,5)だとid < 5となる。 |
NullRef | 指定したフィールド名がNULLであるレコードを検索する。NullRef( title )だと title IS NULL となる。 |
NotNullRef | 指定したフィールド名がNULLではないレコードを検索する。NotNullRef( title )だと title IS NOT NULL となる。 |
今回はモデルクラスのメソッドをまとめてみた。
次回は、実際にモデルを利用して検索/新規作成/更新/削除を行う画面を作成しますよ。