【Spring Boot入門】#4 登録情報一覧画面を作成する

## はじめに
自身の知識のアウトプットも兼ねて、新人研修用に作成した記事となります。Spring Bootを学び始めた方を対象とした内容になっています。

入力チェックの追加については、前回の記事を参照ください。

https://qiita.com/ioaio/items/d382212eeae4434cae9c

## 概要
既に登録済みの企業情報の一覧を表示する画面を作成していきます。
新規登録画面にページ遷移できるようにアンカーリンクも追加します。
また、新規登録後に登録完了画面を表示していたのを、企業情報一覧画面を表示するようにも修正します。

#### 完成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917178/7985036e-cb94-2412-d598-b15d5f4cd204.png)

## パッケージ構成
赤枠で囲ったHTMLファイルを今回作成していきます。また、青枠で囲ったクラスを編集していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917178/0a7f1c3f-faec-817e-26a5-230ba182e5b2.png)

## Serviceクラスの修正
登録済みの企業情報を全件取得するための処理を追加します。
`配置先：src > main > java > com > example > demo > service > CompanyService.java`

```java:CompanyService.java
package com.example.demo.service;

import java.util.List;

@Service
public class CompanyService {
	
	// 企業情報一覧の取得（全件）
	@Transactional
	public List<Company> getAllCompanies() {
		return repository.findAll();
	}
}
```

#### public List<***> メソッド名
`getAllCompanies()` は、企業情報のリスト（`List<Company>`）を返すメソッドです。このメソッドは、データベースからすべての企業情報を取得して返す役割を持っています。
**補足：**`List<Company>`は、companyテーブルに関する情報（Company.java と紐づけられている）をリスト型で返すことを示しています。

#### repository.findAll();
repositoryがデフォルトで持つ`findAll()`メソッドを利用して、データベースから全件の企業情報を取得します。（`SELECT * FROM company;` が実行されるイメージ）


## Controllerクラスの修正
CompanyController.javaに企業情報の一覧画面を表示するメソッドを追加します。
`配置先：src > main > java > com > example > demo > controller > CompanyController.java`

```java:CompanyController.java
@Controller
public class CompanyController {
	
	// 企業情報一覧画面の表示
	@GetMapping("company/lists")
	public String showLists(Model model) {
		model.addAttribute("companies", companyService.getAllCompanies());
		return "index";
	}
}
```
`showLists`メソッドは、`/company/lists`パスへの`GET`リクエストに対し、企業情報の一覧をリスト形式で取得し（※1）、`companies`という名前でビュー（index.html）に渡して表示させる役割を持っています。`index.html`では、この企業一覧データを使って情報を表示できます。

※1：CompanyServiceクラスの`getAllCompanies()`メソッドを呼び出す。

また、登録処理後は企業情報一覧画面（`/company/lists`）へリダイレクトされるように、`addCompany()`メソッド（登録処理）の戻り値を修正します。

```java:CompanyController.java
@Controller
public class CompanyController {
	
	// 企業情報一覧画面の表示

    // 企業情報の新規登録
	@PostMapping("company/register")
	public String addCompany(@ModelAttribute @Validated CompanyForm companyForm,
			BindingResult bindingResult,
			Model model) {
		
		if(bindingResult.hasErrors()) {
			return "register";
		}		
		companyService.createCompany(companyForm);

        /* この部分を修正 */
		// return "thanks";
		return "redirect:/company/lists";
	}
}
```

## Viewの作成
index.htmlを作成します。
`配置先：src > main > resources > templates > index.html`

```html:index.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>企業一覧画面</title>
</head>
<body>
	<h1>企業情報一覧画面</h1>
	<!-- 新規登録画面へのアンカーリンクを追加 -->
	<a th:href="@{/company/register}">新規登録</a>
	
    <!-- 登録企業一覧表示 -->
    <table>
      <thead>
          <tr>
          	<th>ID</th>
            <th>会社名</th>
            <th>従業員数</th>
            <th>設立日</th>
          </tr>
      </thead>
      <tbody>
          <tr th:each="company:${companies}" th:object="${company}">
            <td th:text="*{companyId}"></td>
            <td th:text="*{name}"></td>
            <td th:text="*{employees}"></td>
            <td th:text="*{establishmentDate}"></td>
            <td>
               <!-- 一旦ダミーリンクを設定 -->
			 　<a th:href="@{#}">詳細</a>
			   <a th:href="@{#}">編集</a>
			   <a th:href="@{#}">削除</a>
            </td>
          </tr>
      </tbody>
    </table>
</body>
```

#### th:href="@{path}"
`th:href="@{/company/register}"` により、`/company/register`というURLにリンクされます。つまり、このアンカーリンクを押下することでユーザーは企業情報登録画面へと遷移されます。

#### th:each="company:${companies}"
`th:each` はループ処理を行うための属性で、`companies`リストの各要素を`company`として一つずつ取り出して処理しています。

#### th:object="${company}"
`company`オブジェクト（Company.java）を参照することを意味します。

#### th:text="*{...}"
`*{...}` は `th:object`で指定された`company`オブジェクトのプロパティを参照します。つまり、`th:text="*{companyId}"`のように `company`オブジェクトの各プロパティ（`companyId`, `name`, `employees`, `establishmentDate`）を表示しています。

:::note
**補足**
今回は `company`オブジェクトを参照する方法（`th:object="${company}"`）で書いていますが、次のように書くことも可能です。
```java:index.html
     <tbody>
          <tr th:each="c:${companies}">
            <td th:text="*{c.companyId}"></td>
            <td th:text="*{c.name}"></td>
            <td th:text="*{c.employees}"></td>
            <td th:text="*{c.establishmentDate}"></td>
            <td>
               <!-- 一旦ダミーリンクを設定 -->
                <a th:href="@{#}">詳細</a>
                <a th:href="@{#}">編集</a>
                <a th:href="@{#}">削除</a>
            </td>
          </tr>
      </tbody>
```
:::
## データの流れ
企業情報一覧画面が表示されるまでの流れは以下の通りです。

1. ユーザーがブラウザで `/company/lists` にアクセスする
2. `showLists()`メソッドが呼び出され、`companyService`から企業情報のリストを取得される
3. `Model` オブジェクトにリストが追加され、`index.html`でその情報が表示される

次回はIDによる検索機能を実装していきます。

## 参考サイト
https://www.microstone.info/spring-boot-2%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80%EF%BC%9A%E7%B0%A1%E5%8D%98%E3%81%AAweb%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92%E4%B8%80%E3%81%8B%E3%82%89%E4%BD%9C%E6%88%90%E3%83%81%E3%83%A5%E3%83%BC/