レコードの一覧表示機能の実装

今回のお題

今回のお題は「レコードの一覧表示機能の実装」です。

前回が保存機能だったので、その続きですね。

具体的には、UserコントローラのuserListメソッドを介してuser/list.htmlを表示した際にm_userテーブルに保存されているレコードを一覧表示するという流れに沿って、一覧表示機能の実装手順を解説していきます。

目次

  • 全体の流れ
  • application.propertiesの編集
  • DB操作関数の定義
  • SQL文の記述
  • インスタンス生成用の関数の定義
  • コントローラの編集
  • ビューの編集

全体の流れ

m_userテーブルのレコードを一覧表示する際にコンピュータの内部で行われていることは、

  1. m_userテーブルのレコードを配列の形で取得する。
  2. 取得した配列を元に、MUserモデルのインスタンスを作成する。
  3. 生成したMUserのインスタンスをビューで表示する。

以上になるので、こちら側で記述するべき内容としては

  1. インターフェースを作成し、DB操作関数を定義する。
  2. UserMapper.xmlに、1で作成した関数に対応するSQL文を記述する。
  3. 1とは別のインターフェースを作成し、MUserモデルのインスタンス作成のための関数を定義する。
  4. 3で定義した関数の中身を記述する。
  5. 4の関数を用いてコントローラ内でインスタンスを作成できるようにする。
  6. 作成したインスタンスをビューで表示する。

ということになります。

ですが、その前に少し下準備があるので、まずはそちらを行っていきます。

application.propertiesの編集

まずは、application.propertiesに以下の内容を追加します。

 

mybatis.configuration.map-underscore-to-camel-case=true
mybatis.type-aliases-package=com.example.demo.domain.user.model

 

1行目については、ModelMapperクラスのmapメソッドの補助をする設定になります。

この記述があると、アンダースコア表記のフィールド(user_idなど)とキャメルケース表記のフィールド名(userId)を同一と見做してmapメソッドを実行してくれます。

 

Javaクラスのインスタンスフィールド名は基本的にキャメルケースで記述しますが、DBのカラム名は慣例としてスネークケースもあり得るので、そこを気にしなくてよくなるのはありがたいですね。

 

2行目については、ModelMapperのパッケージ名を省略するための記述になります。

この後ModelMapper(今回でいうとUserMapper)のパッケージ名を記述する場面があるのですが、application.propertiesにこのように記述しておくことでファイル名のみの記述で済むようになります。

 

では、準備が済んだところでインターフェースにDB操作関数を定義していきます。

DB操作関数の定義

まずはインターフェース内にDB操作関数を定義していきます。

インターフェースはなければ作成しますが、あれば既存のものでも構いません。

今回は、以前にユーザー保存機能を実装した際のインターフェースを使用します。

 

UserMapper.javaに以下を追加してください。

public List<MUser> findMany();

 

MUserを要素とする配列を取得するfindMany関数を定義しました。

次は、UserMapper.xmlを編集してこの関数に対応するSQL文を書いていきます。

UserMapper.xmlの編集

UserMapper.xmlに、以下の内容を追加してください。

 

<select id="findMany" resultType="MUser">
        select * from m_user

</select>

 

注意点は以下の通りです。

  • SQL文がselectで始まる時は<select>タグで囲む。
    前回はinsert文だったのでinsertタグを用いましたが、今回はselect文なのでタグもそれに合わせます。
  • id属性の値としてDB操作関数の名前を指定する。
  • select文を使用する場合には、resultType属性を用いて戻り値の型を指定する。
    今回はMUserモデルを指定。
    戻り値が一つの場合には、StringやIntegerも指定可能。
    ちなみに、上記のapplication.propertiesでpackageのエイリアスを指定していない場合には、MUserの部分にパッケージ名も含める必要があります。

今回は、m_userテーブルかに登録されているレコードを全件取得しています。

これで、レコードを配列の形で取得することができました。

次に、ここからMUserクラスのインスタンスを作成していきます。

インスタンスを作成する関数の定義

インターフェースを用意し、インスタンスを作成する関数を定義していきます。

今回は、レコード保存に使用したUserService.javaを使用します。

 

以下を記述してください。

public List<MUser> getUsers();

MUserのインスタンスを要素にもつ配列を返すgetUserメソッドを定義しています。

 

次に、このインターフェースを継承したクラスを用いてメソッドの中身を定義していきます。

UserServiceImplの編集

UserServiceImpl.javaに以下の内容を追加します。

@Autowired

public List<MUser> getUsers(){
    return mapper.findMany();

}

ModelMapperクラスであるUserMapperに定義した、findMany()メソッドを用いてm_userテーブルから配列を取得しています。

次に、この配列をコントローラに渡します。

コントローラの編集

UserListControllerを編集します。

// 追加

@Autowired

private UserService userService;

// 編集

public String getUserList(Model model){

    List<MUser> userList = userService.getUsers();

    model.addAttribute("userList", userList);

    return "user/list";

}

getUserメソッドを用いて取得したレコードをuserListという変数に代入し、"userList"というキー名でmodelに登録しています。

最後に、modelの中身をビューで表示します。

ビューの編集

userListは配列なので、基本的には以下のようにeachを用いて展開します。

<tr th:each="item:${userList}">

    <td th:text="${item.name}"></td>
    <td th:text="${item.gender == 1}?'男性':'女性'"></td>

    <td th:text="${#dates.format(item.birthday, 'YYYY/MM/dd')}"></td>

</tr>

 

以下、赤字部分の解説です。

"${item.gender == 1}?'男性':'女性'"

Javaの3項式をth表記に直したものですね。

条件式?"a":"b"の形で、条件式がtrueの場合には"a"、そうでなければ"b"が表示されます。

3項式の例)String message = hour <= 12 ? "午前": "午後"

この例だと、hourという変数が12以下であればmessageという変数に"午前”という文字列が、hourが12より大きければ"午後"という文字列が代入されます。

 

genderの例だと、genderカラムが1であれば"男性", 2であれば"女性"と表示されます。

 

"${#dates.format(item.birthday, 'YYYY/MM/dd')}"

に関しては、birthdayカラムの値をYYYY/MM/dd形式に変換して表示しています。