データを表示する
では、保存したデータを表示させてみましょう。これは、indexアクションを書き換えて作成します。まず、アクションメソッドを修正しましょう。
public static void index() {
List<MsgData> datas = MsgData.findAll();
render(datas);
}
非常にシンプルです。MsgDataの全データを取得するには「findAll」というメソッドを呼び出すだけです。これは、MsgDataインスタンスのListとして値を返します。ここではそれをdatasという変数に受け取り、renderの引数に渡して呼び出しています。後はテンプレート側で、このdatasから順にMsgDataを取り出し、必要な値を書き出していけばいいでしょう。
#{extends 'main.html' /}
#{set title:'Home' /}
<h1>メッセージ表示</h1>
#{list items:datas, as:'data'}
<li>${data.id}: ${data.message}(${data.name})</li>
#{/list}

ここでは、#{list items:datas, as:'data'}~#{/list}という部分で、datasから値を順に取り出しては変数dataに設定する、といったことを繰り返し実行しています。これは次のような形で記述されます。
#{list items:変数名, as:'代入する変数名'}
items:の後に、Listが収められている変数を指定します。すると、そこから順にオブジェクトを取り出し、as:で指定した変数に代入しては#{/list}までの処理を繰り返していきます。取り出した値はMsgDataインスタンスであるはずですから、${data.message}というようにしてmessageフィールドの値を書き出すことができます。
ところで、ここではよく見ると、最初に${data.id}というものが書かれています。これは、インスタンスの「id」の値を書き出すものです。しかし、考えてみるとMsgDataには「id」というフィールドは用意されていません。
このidフィールドは、モデル・クラスに自動的に追加される特別なフィールドなのです。すべてのMsgDataインスタンスにはこのidが用意されており、それらにはすべてユニークな値が自動的に割り振られます。要するに「自動生成されるプライマリキー」というわけです。
データの検索
すべてのデータを取り出すなら、findAllで簡単に行えましたが、では特定の条件に合致するものを検索する場合にはどうすればよいのでしょう。先ほどのindexアクションを書き換えて、nameで検索するようにしてみましょう。
#{extends 'main.html' /}
#{set title:'Home' /}
<h1>メッセージ表示</h1>
<form method="post" action="@{Application.index}">
name:<input type="text" name="name" />
<input type="submit" value="送信" />
</form>
<hr />
#{list items:datas, as:'data'}
<li>${data.id}: ${data.message}(${data.name})</li>
#{/list}
index.htmlを修正し、フォームを追加します。ここから入力されたnameを送信し、それをもとにデータを検索して表示しよう、というわけです。では、indexメソッドの修正を行いましょう。
public static void index(String name) {
List<MsgData> datas = null;
if (request.method.equals("POST")) {
datas = MsgData.find("name like ?", "%" + name + "%").fetch();
} else {
datas = MsgData.findAll();
}
render(datas);
}

これで完成です。ブラウザからindexにアクセスし、名前を入力して送信してみましょう。その名前を含むデータだけが検索されます。ここでは、POSTで送信されると、次のようにしてデータを取得しています。
datas = MsgData.find("name like ?", "%" + name + "%").fetch();
「find」は、引数をもとに、実際にデータベースからデータを取得するためのJPAQueryというインスタンスを生成します。このJPAQueryから「fetch」メソッドを呼び出すことで、実際にデータがListとして取得されます。
findでは、"name like ?"という簡単なクエリーが第1引数に指定されています。この?の部分に、第2引数の"%"+name+"%"がはめ込まれます。つまり、"name like %テキスト%"といったものが実行されていたわけです。
これは、SQLのクエリーに似ていますが、selectなどが記述されていません。これは「JPQLクエリー」というものでJPAで使われる簡易クエリーです。「SQLクエリーを使わないですむといっても、結局似たようなものを書かないといけないのか」と思われたかもしれません。確かにそのとおりで、まだモデル部分の実装は不完全なように見受けられます。データの作成や修正、削除などはメソッドを呼ぶだけなのですが、細かな検索についてはまだこのようにクエリーを書かなければいけない部分が残っています。
といっても、単純に「このプロパティの値=チェックする値」というように、シンプルな検索であれば、クエリーらしいクエリーを書く必要もなく、ただ単に「find( プロパティ名 , 値 )」と呼び出すだけで十分です。クエリーを書くのはこまごまとした検索の設定を必要とされる場合のみと考えておきましょう。
