【Spring Boot入門】#5 ID検索機能を作成する

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

登録情報一覧画面の表示については、前回の記事を参照ください。

https://qiita.com/ioaio/items/8fde25d6c2c27a95d9a3

## 概要
検索ボックスを追加し、企業IDに紐づく企業情報を検索できるようにする機能を作成します。

#### 完成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917178/52b635b5-8acd-2a85-11e4-10fa4462bbf3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917178/5525a929-8588-cf6f-453a-7c2ffefd044a.png)

未登録の企業IDが検索された場合は、エラーメッセージを表示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917178/51035ee9-e06c-8c94-8183-759815bd851e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917178/3939f365-051e-4327-7bc4-4cea424d00f0.png)

## パッケージ構成
赤枠で囲ったHTMLファイルを今回作成していきます。また、青枠で囲ったクラスを編集していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917178/b82d82d6-11d7-6ac7-f64c-01667b94a0cb.png)


## Serviceクラスの修正
指定したIDの企業情報をデータベースから取得するための処理を追加します。
`配置先：src > main > java > com > example > demo > service > CompanyService.java`

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

import java.util.Optional;

@Service
public class CompanyService {
	
	// 企業情報一覧の取得（全件）

    // 企業IDによる企業情報の取得（１件）
	@Transactional
	public Optional<Company> getCompanyById(Long companyId) {
		return repository.findById(companyId);
	}
}
```
#### public Optional<***> メソッド名(引数)
`getCompanyById()`は、指定した`companyId`をもとにデータベースから企業情報を1件取得しようとするメソッドです。メソッドの引数として、`Long` 型の `companyId`を受け取ります。

このメソッドの戻り値は`Optional<Company>`です。`Optional`は、結果が存在しない可能性のある場合に使用されるクラスであり、`Optional`を使用することで呼び出し元でのnullチェックを簡単に行うことができます。

#### repository.findById(companyId);
repositoryがデフォルトで持つ `findById` メソッドを利用して、データベースから `companyId` に紐づく特定の企業情報を1件検索します。（`SELECT * FROM company WHERE company_id = "企業ID";` が実行されるイメージ）

`findById` メソッドは、データが見つからなかった場合に `Optional.empty()` を返し、データが見つかった場合は `Optional` に `Company`オブジェクトを格納して返します。

## Controllerクラスの修正
CompanyController.javaにID検索をするメソッドを追加します。

`配置先：src > main > java > com > example > demo > controller > CompanyController.java`

```java:CompanyController.java
@Controller
public class CompanyController {
	
	// 企業情報一覧画面の表示
 
	// ID検索処理
    @GetMapping("company/search")
	public String search(@RequestParam Long companyId, Model model) {
		model.addAttribute("companies", companyService.getCompanyById(companyId).orElse(null));
		return "index";
	}
}
```
#### @￰RequestParam Long companyId
`@RequestParam` アノテーションは、リクエストパラメータを取得するためのアノテーションです。

リクエストパラメータの `companyId` を取得し、Long型の変数 `companyId` に格納します。このパラメータは、URLに「?companyId=123」のように付与することで渡されます。

#### companyService.getCompanyById(companyId).orElse(null)
・`companyService.getCompanyById(companyId)`：
`companyService`（サービスクラス）の `getCompanyById` メソッドを呼び出し、引数として渡した `companyId`を持つ企業情報を取得します。

・`.orElse(null)`：
もし指定された `companyId` の企業が見つからなかった場合、`null`を返します。

:::note warn
今回は指定された企業IDに基づいて企業情報を取得し、Viewに表示するだけのシンプルな実装となっています。
本来は、企業IDが入力されなかったり無効な値が入った場合にエラーハンドリングを行う必要があります。
:::

## Viewの修正
index.htmlに検索ボックスを追加します。また、未登録の企業IDが検索された場合にメッセージが表示されるようにします。
`配置先：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>
 
	<!-- 検索ボックス -->
	<form th:action="@{/company/search}" method="get">
	  <input type="text" name="companyId" placeholder="企業IDを入力してください">
	  <button type="submit">検索</button>
	</form>
	
	<!-- 検索対象の企業IDが未登録の場合にメッセージを表示 -->
    <div th:if="!${companies}">
      <p>登録された企業はありません。</p>
    </div>
    
    <!-- 登録企業一覧表示 -->
    
</body>
```
#### 検索ボックス
入力された企業ID（`companyId`）はクエリパラメータとして `/company/search` エンドポイントにGETリクエスト（`method="get"`）で送信されます。

#### メッセージの表示
`th:if="!${companies}"` で `companies`オブジェクトが `null` または `空` である場合にのみ、この `<div>` が表示される条件を設定しています。つまり、検索IDに紐づく企業が1件も登録されていないときに「登録された企業はありません。」とメッセージが表示されます。

## データの流れ
企業IDに基づく企業情報を検索し、検索結果が表示されるまでの流れは以下の通りです。

1. ユーザーが検索ボックスに企業IDを入力し、「検索」ボタンを押下する
2. リクエストパラメータである `companyId` は「/company/search?companyId=123」のような形でコントローラーへ渡される
3. `CompanyController` の `search` メソッドが呼び出され、companyId が 123として取得される
4. `companyService` の `getCompanyById` が呼び出され、IDが123の企業情報がデータベースから取得される
5. 取得された企業情報がモデルに設定される
6. ビュー（`index.html`）がレンダリングされ、ブラウザに表示される

次回は登録データの詳細画面を実装していきます。