モデル操作の詳細
これまでの例で、モデルを定義して操作する方法の概要を説明しました。ここでは、モデルの持つAPIについて、もう少し詳しく解説します。
データの作成・登録・削除
モデルのインスタンスを新規に作成するには、MetaMapperオブジェクトが持つcreate関数を使用します。newでインスタンスを作成すると、モデルのデータに不整合が生じる可能性があるので、必ずcreate関数を使用してモデルを作成するようにしてください。
scala> val msg = Message.create
msg: demo.twitterclone.model.Message = demo.twitterclone.model.Message={id=-1,user=NULL,status=,dateof=Tue Oct 20 15:55:28 JST 2009}
モデルのプロパティの取得は、単純にプロパティ名の関数を呼び出すことで取得できます。プロパティにデータを設定する場合は、プロパティ名(値)のように設定したい値を引数に渡すだけです。プロパティの設定は、メソッドチェーンのように続けて設定することができるようになっています。
// プロパティの設定
scala> msg.status( "say hello ").dateOf( new Date )
res1: demo.twitterclone.model.Message = demo.twitterclone.model.Message={id=-1,user=NULL,status=say hello ,dateof=Tue Oct 20 16:05:37 JST 2009}
// プロパティの取得
scala> msg.status
res2: msg.status.type = say hello
モデルをデータベースに保存するには、save関数を呼び出します。モデルが新規作成された物であればINSERTが、既に存在するデータであればUPDATEが実行されます。保存が正常に実行されると、trueが戻り値として返されます。
// save関数を呼び出してデータを保存 scala> msg.save res3: Boolean = true
モデルをデータベースから削除するには、delete_!関数を利用します。削除が正常に実行されると、trueが戻り値として返されます。
// delete_!関数を呼び出してデータを削除 scala> msg.delete_! res4: Boolean = true
データの検索
データベースから検索を行うには、MetaMapperオブジェクトが持つfindAll関数を使用します。findAll関数は該当するレコードを全件Listで返します。単純な全件検索は、MetaMapperオブジェクトのfindAll関数を呼び出すだけです。
scala> Message.findAll
res9: List[demo.twitterclone.model.Message] = List(demo.twitterclone.model.Message={id=1,user=NULL,status=helle,dateof=2009-10-19 00:00:00.0}, demo.twitterclone.model.Message={id=3,user=NULL,status=test01,dateof=2009-10-20 00:00:00.0}, demo.twitterclone.model.Message={id=4,user=NULL,status=test02,dateof=2009-10-20 00:00:00.0})
通常のデータの検索では、検索条件を指定して検索を行うことがほとんどでしょう。検索条件は、QueryParamクラスを利用して、findAll関数の引数に与えることで指定できます。
findAll関数の定義は次のようになっています。
findAll(by: QueryParam[A]*): List[A]
定義の中のA型はモデルの型になります。関数の引数であるQueryParam[A]は、検索条件を表すtraitです。*が付いているので、可変長引数として複数の検索条件を指定できます。
具体的な使い方を見てみましょう。リスト12の例では、Messageモデルのstatusプロパティが"test01"に一致するデータを検索しています。findAll関数にBy(プロパティ,値)の形式で検索条件を指定しているのです。
scala> Message.findAll(By( Message.status, "test01") )
res8: List[demo.twitterclone.model.Message] = List(demo.twitterclone.model.Message={id=3,user=NULL,status=test01,dateof=2009-10-20 00:00:00.0})
リスト12で利用したBy以外にも、検索条件として比較やLIKEなどができます。リスト13の例では、Like(プロパティ,文字列)でstatusが"test"から始まる文字列を検索し、By_>(プロパティ,値)で1日前から後に投稿されたものを検索しています。
scala> import java.util.Calendar
import java.util.Calendar
scala> val c = Calendar.getInstance
c: java.util.Calendar = java.util.GregorianCalendar[time=1256026093937,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Tokyo",offset=32400000,dstSavings=0,useDaylight=false,transitions=10,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2009,MONTH=9,WEEK_OF_YEAR=43,WEEK_OF_MONTH=4,DAY_OF_MONTH=20,DAY_OF_YEAR=293,DAY_OF_WE...
scala> c.add( Calendar.DATE , -1 )
scala> Message.findAll(Like( Message.status, "test%") ,By_>( Message.dateOf , c.getTime ))
res29: List[demo.twitterclone.model.Message] = List(demo.twitterclone.model.Message={id=3,user=NULL,status=test01,dateof=2009-10-20 00:00:00.0}, demo.twitterclone.model.Message={id=4,user=NULL,status=test02,dateof=2009-10-20 00:00:00.0})
以下の表は、findAll関数の検索条件として指定できるものです。
| 条件 | 説明 |
| By(プロパティ,値) | 指定したプロパティ名で、一致する値のレコードを検索する。By(title,"hogehoge")だとtitle='hogehoge'となる。 |
| NotBy(プロパティ,値) | 指定したプロパティ名で、一致しない値のレコードを検索する。NotBy(title,"hogehoge")だとtitle<>'hogehoge'となる。 |
| 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となる。 |
| Like(プロパティ,値) | 指定したプロパティ名でLIKE検索する。Like(title,"foo%")だとtitle LIKE 'foo%'となる。 |
まとめ
以上が、LiftのModelについての概要と簡単な使い方についての解説です。LiftのMapper and Record Frameworkは、ここで紹介した機能の他に、SQLを指定しての検索やテーブル間のリレーションの定義などもできるようになっています。
今回は、Modelを定義して対話型インタプリタでの動作確認までしか説明できませんでしたが、次回は、第2回のView層の解説で作成したTwitterクローンアプリケーションと今回作成したモデルを組み合わせて、SnippetとModelを組み合わせる方法を解説する予定です。
参考資料
- The Scala Programing Language
- Lift
- 『Programming in Scala』Martin Odersky・Lex Spoon・Bill Venners 著、Artima Inc、2008年11月
- 『The Definitive Guide to Lift: A Scala-based Web Framework』Derek Chen-Becker・Tyler Weir・Marius Danciu 著、Apress、2009年5月
