Spring Bootでチェックボックスから取得した値をDBに登録する

# 開発環境
・macOS Monterey Version 12.6.3
・Spring Tool Suite Version: 4.17.2.RELEASE
・MySQL 8.0.32
・Sequel Ace Version 4.0.5

# 実現したい処理
新規登録画面に入力欄(テキスト、テキストエリア)、ファイル選択ボタン、宛先選択ボタン、保存ボタンを表示する。

→宛先選択ボタン押下時にモーダルウインドウを表示する。
モーダルウインドウ内に、ユーザー名やメールアドレスが登録されているDBから検索した文字列とチェックボックスをテーブルに表示し、最下部に決定ボタンと閉じるボタンを表示する。

→チェックボックスにチェックを入れ　(複数選択可)、モーダルウインドウ内の決定ボタンを押下すると、モーダルウインドウを閉じる。

→新規登録画面に戻り、保存ボタンを押下すると、チェックボックスの入力から取得されたIDが文字列としてDBに登録される。(複数選択された場合はカンマ区切りとなる)
※この時使用するDBは、モーダル内で使用したものとは別。

# サンプルコード
▷DB
・新規登録画面で登録する際に使用するテーブル![スクリーンショット 2023-03-08 23.08.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3075609/02c6c1d4-0a1c-18fe-c9cd-e28ece15264d.png)
selected_idsが今回チェックボックスの入力に対応させるカラムとなる。
(今回はAllow Nullにチェックが入っているが、外した方が良いかも)

・モーダル内に表示させるテーブル
![スクリーンショット 2023-03-08 23.09.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3075609/91cb3d41-8270-c87a-ae7c-2fc580367793.png)
今回はID取得に焦点を当てているため、ほかのカラムは適当でOK。

▷HTML
scriptタグ内の関数によって、チェックボックスから取得したIDを処理している。

```html
<body>
	<!--見出し-->
	<div class="header">
		<h2>新規登録</h2>
	</div>
	<!--フォーム-->
	<form method="post" th:action="@{/upload}" enctype="multipart/form-data" class="input">

		<section class="button_area">
			<input type="button" onclick="location.href='#'" value="戻る"
				control-id="ControlID-1">
		</section>
		<!--動画(ファイルが存在する場合のみ表示される)-->
		<span th:if="${base64video}">
			<div class="video">
				<video controls th:src="${'data:video/mp4;base64,' + base64video}"></video>
			</div>
		</span>
		<!--テーブル-->
		<table class="input_area">
			<tbody>
				<tr>
					<td>概要</td>
					<!--入力-->
					<td><input type="text" th:value="${outline}" name="outline" control-id="ControlID-2" /></td>
				</tr>
				<tr>
					<td>説明</td>
					<!--入力-->
					<td><textarea name="explanation" control-id="ControlID-3">[[${explanation}]]</textarea></td>
				</tr>
				<tr>
					<td>ファイル</td>
					<!--入力-->
					<td>
						<label>
							<input type="file" accept="video/*" class="file_upload" name="video"
								onchange="selectFile(this)">ファイルを選択
						</label>
						<div id="fileUploadText">
							<p id="fileUploadTextMsg" style="display: none;">ファイルが選択されました</p>
						</div>
					</td>
				</tr>
				<tr>
					<td>宛先</td>
					<!--入力-->
					<td>
						<!--宛先選択ボタン-->
						<div class="chooseAddress">
							<input type="button" id="openModal" value="宛先選択">
						</div>
					</td>
				</tr>
			</tbody>
		</table>
		<!--保存ボタン-->
		<section class="button_save">
			<input type="hidden" id="selected_ids" name="selected_ids" th:value="${selected_ids}">
			<input type="submit" value="保存" control-id="ControlID-4">
		</section>
	</form>
	<!--モーダル(宛先選択画面)-->
	<div id="modal" class="modal">
		<div class="modal-content">
			<div class="modal-header">
				<h2>ユーザー</h2>
			</div>
			<div class="modal-body">
				<div class="modal-inptArea">
					<input type="text" class="inpt" id="modal_input" name="name" placeholder="検索するユーザー名を入力" />
					<input type="submit" id="searchButton" value="検索">
				</div>
				<!-- 表 -->
				<section class="chart">
					<table>
						<tbody>
							<tr th:each="user : ${userlists}">
								<td>
									<!--チェックボックス-->
									<input type="checkbox" name="checks" th:value="${user.id}">
								</td>
								<td th:text="${user.name}"></td>
								<td th:text="${user.mail}"></td>
							</tr>
						</tbody>
					</table>
				</section>
				<!--モーダル内ボタン-->
				<div id="btnArea3">
					<!--決定ボタン-->
					<input type="submit" id="decide" class="accent" name="decideBtn" value="決定">
					<!--閉じるボタン-->
					<button type="button" id="buttonClose" class="accent" name="fallbackBtn">
						閉じる
					</button>
				</div>
			</div>
		</div>
	</div>

	<!--JS-->
	<script>
		$(function () {
			//モーダル表示/非表示
			const $buttonOpen = $('#openModal');
			const $buttonDecide = $('#decide');
			const $buttonClose = $('#buttonClose');
			const $modal = $('#modal');
			// 宛先選択ボタンがクリックされた時
			$buttonOpen.click(function () {
				$modal.addClass("block");
			});

			// 閉じるボタンがクリックされた時
			$buttonClose.click(function () {
				$modal.removeClass("block");
			});

			// 決定ボタンをクリックしたときの処理
			$('#modal #decide').click(function () {
				//チェックボックスから取得したidをカンマ区切りで配列に格納する
				let selectedIds = [];
				$('#modal input[name="checks"]:checked').each(function () {
					selectedIds.push($(this).val());
				});
				$('#selected_ids').val(selectedIds.join(','));
				//モーダルを閉じる
				$modal.removeClass("block");
			});
		});
	</script>

</body>

```
▷Java
```java
package com.controller;
//import文は省略

@Controller
public class CreateController {

	// taskテーブル用リポジトリ
	@Autowired
	private TaskRepository taskRep;
	@Autowired
	private UserRepository userRep;

	// 画面名
	private static final String PAGE_NAME = "create";

	// 作成画面
	@GetMapping("/create")
	@Transactional
	public String disp(Model model, User user) {
		// モーダル用：Userテーブルから全てのレコードを取得する
		List<User> userlist = userRep.findAll();
		// モデル設定
		model.addAttribute("userlists", userlist);
		model.addAttribute("taskForm", new TaskForm());
		// 画面遷移
		return PAGE_NAME;
	}

	// 概要、説明、動画ファイル、宛先をDBに登録する
	@PostMapping("/upload")
	@Transactional
	public String upload(@RequestParam("video") MultipartFile video, @RequestParam("outline") String outline,
			@RequestParam("explanation") String explanation, @RequestParam("selected_ids") String selected_ids,
			Model model, User user) throws IOException {
		// インスタンス
		Task task = new Task();
		// videoをbyte型に変換
		byte[] cvideo = video.getBytes();
		// base64にエンコード
		String encodedVideo = Base64.getEncoder().encodeToString(cvideo);
		//setter
		task.setVideo(cvideo);
		task.setOutline(outline);
		task.setExplanation(explanation);
		task.setSelectedIds(selected_ids);
		// DB登録
		taskRep.save(task);
		// モデル
		model.addAttribute("outline", outline);
		model.addAttribute("explanation", explanation);
		model.addAttribute("base64video", encodedVideo);
		model.addAttribute("selected_ids", selected_ids);
		//画面遷移
		return disp (model, user);
	}
}
```
以上