SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Scala+Liftによる実践Webアプリケーション開発

Scala+LiftフレームワークのModel

Scala+Liftによる実践Webアプリケーション開発(3)

モデル操作の詳細

 これまでの例で、モデルを定義して操作する方法の概要を説明しました。ここでは、モデルの持つAPIについて、もう少し詳しく解説します。

データの作成・登録・削除

 モデルのインスタンスを新規に作成するには、MetaMapperオブジェクトが持つcreate関数を使用します。newでインスタンスを作成すると、モデルのデータに不整合が生じる可能性があるので、必ずcreate関数を使用してモデルを作成するようにしてください。

[リスト7]モデルの作成
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}

 モデルのプロパティの取得は、単純にプロパティ名の関数を呼び出すことで取得できます。プロパティにデータを設定する場合は、プロパティ名(値)のように設定したい値を引数に渡すだけです。プロパティの設定は、メソッドチェーンのように続けて設定することができるようになっています。

[リスト8]プロパティの取得/設定
// プロパティの設定
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が戻り値として返されます。

[リスト9]モデルの保存
// save関数を呼び出してデータを保存
scala> msg.save
res3: Boolean = true

 モデルをデータベースから削除するには、delete_!関数を利用します。削除が正常に実行されると、trueが戻り値として返されます。

[リスト10]モデルの削除
// delete_!関数を呼び出してデータを削除
scala> msg.delete_!
res4: Boolean = true
データの検索

 データベースから検索を行うには、MetaMapperオブジェクトが持つfindAll関数を使用します。findAll関数は該当するレコードを全件Listで返します。単純な全件検索は、MetaMapperオブジェクトのfindAll関数を呼び出すだけです。

[リスト11]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(プロパティ,値)の形式で検索条件を指定しているのです。

[リスト12]findAll関数による全件検索
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日前から後に投稿されたものを検索しています。

[リスト13]findAll関数による全件検索
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関数の検索条件として指定できるものです。

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を組み合わせる方法を解説する予定です。

参考資料

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
Scala+Liftによる実践Webアプリケーション開発連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 尾崎 智仁(オザキ トモヒト)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4648 2009/12/30 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー