MyBatis+SpringBootでCRUDアプリを作る ※余計なものはナシ※ 1/2

MyBatisを使ったToDoリストを作成します。
目標物はこれ↓
![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044070/e731eda6-3645-23d9-11a3-753a460b58b4.gif)



- やることを登録（blankは登録できない）
- やることを見る
- やることを変更
- やることを消去  
以上ができる単純なアプリです。

# 作成した経緯
SpringBootのCRUDができる書籍はありますが、MyBatisを使ったものは少ないです。（ほぼJPAかJDBC）
また、BootstrapやJSが混ざったもの、HTMLが複雑なものも多く、私が理解しづらかったため、わかりやすくシンプルなものにしてみました。

# 対象者
- Controller、Service、Repositoryが何をしている何となくわかる人。
- CRUDが何かわかる人。
- JPAやJDBCがなんとなくわかる人。
- MyBatisを初めて使う人。

# 使っている環境
■OS : Windows10
■IDE : Eclipse
■Maven
■SpringBoot
■DB : MySQL8.0.22

# MyBatisとは
簡単に言えばDBに接続してSQL文を実行してくれるものです。(O/Rマッパー)
JDBCより簡単で、JSPより細かいSQL文が実行できます。
今まではおそらくRepositoryクラスで作成されていたものが、今回はMapperクラスとなります。
XMLに書くこともできるのですが、今回は分かりやすいのでアノテーションに書いていきます。
（こっちの方が新しい書き方のようです）

# 1-1.pom.xml
今回DBはMySQL、O/RマッパーにMyBatis、バリデーション機能を使うので3つをapplicationに追加します。

```xml
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.1.4</version>
		</dependency>
　　　　　　　　　<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-validation</artifactId>
		</dependency>
```

# 1-2.application.properties
MySQLへの接続をします。

```properties
#MySQLのDBのURL
spring.datasource.url=jdbc:mysql://localhost:3306/xxxxxxx?serverTimezone=JST

#name、password指定。
spring.datasource.username=root
spring.datasource.password=xxxxxxxx

#SpringBootを起動したときに実行したいSQL文を記述したパス
#schemaにはテーブルを作るSQLを入れておく
spring.datasource.schema=classpath:schema.sql

#これがないとputやdeleteでエラーになる
spring.mvc.hiddenmethod.filter.enabled=true
```
ご自身のMySQLの環境に合わせてください。
spring.mvc.hiddenmethod.filter.enabled=true がないとエラーになります。
ここで私はハマりましたww
![qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044070/0e356bc2-7af8-f859-f718-a207731d5113.png)

htmlのhttpメソッドでdeleteとputを使っているので必要になります。
getとpostで書けば不要となります。
その場合はControllerのアノテーションも`@GetMapping`に揃えてください。
↓こちらを参考にさせていただきました。
https://qiita.com/kazuhiro1982/items/b8b9965fddf9c5507517


# 1-3.MySQLでテーブルを作る
```SQL
CREATE TABLE IF NOT EXISTS todo (
  id bigint(20) NOT NULL AUTO_INCREMENT,
  task varchar(255) DEFAULT NULL,
  PRIMARY KEY (id)
);
```
特に難しいSQLではないですが
NOT EXISTSはもうテーブルが存在するなら、再度作らない。
AUTO_INCREMENTは連続した番号を付ける。

# 2-1.top.html(最初の画面)
```html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
	xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
	layout:decorator="layout">
<meta charset="UTF-8">
<title>ToDOリスト</title>

</head>
<body>
	<h1>ToDoリスト</h1>
	<a th:href="@{/todos/new}">
		<button>ToDo作成【NEW】</button>
	</a>
	<div th:if="!${todo.size()}">
		<p>該当の検索結果がありません！</p>
	</div>
	<table th:if="${todo.size()}" border="1">
		<thead>
			<tr>
				<th>ID#</th>
				<th>やること</th>
				<th></th>
				<th></th>
				<th></th>
			</tr>
		</thead>
		<tbody>
			<tr th:each="todo:${todo}" th:object="${todo}">
				<!-- each;DBの情報をすべて出すまで繰り返す -->
				<td th:text="*{id}"></td>
				<td th:text="*{task}"></td>
				<td><a th:href="@{/todos/{id}(id=*{id})}">
						<button>詳細</button>
				</a></td>
				<td><a th:href="@{/todos/{id}/change(id=*{id})}"><button>変更</button></a></td>
				<td>
					<form th:action="@{/todos/{id}/delete(id=*{id})}"
						th:method="delete">
						<button>消去</button>
					</form>
				</td>
			</tr>
		</tbody>

	</table>
</body>
</html>
```

>th:if="${todo.size()

todoが何も登録していないときは「該当の検索結果がありません！」と表示

>th:each="todo:${todo}" th:object="${todo}

todoが全部終わるまで、todoの中身を表示

>th:text="*{id}" th:text="*{task}"

todoの中身のidとtaskを表示
>th:method="delete"

Controllerの`@DeleteMapping`に対応します。
get、post以外にも出てくるんです。

# 2-2.new.html(登録画面)
```html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
	xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
	layout:decorator="layout">
<meta charset="UTF-8">
<title>新規ToDo</title>
</head>
<body>

	<h2>新規ToDo作成</h2>

	<form method="post" th:action="@{/todos/new}" th:object="${todo}">
		<ul>
			<li><label>やること</label> <br> <input type="text" id="task"
				name="task" th:field="*{task}" /> 

			</li>

		</ul>

		<button >新規作成</button>
	</form>
</body>
</html>
```
>th:action="@{/todos/new}"　th:object="${todo}"　th:field="*{task}"

objectのtodoの中に、taskを詰めて、controllerのtodos/newに渡します。

# 2-3.show.html(確認画面)
```html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
	xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
	layout:decorator="layout">
<meta charset="UTF-8">
<title>todo</title>

</head>
<body>
	<h2>登録内容確認</h2>
	<div th:object="${todo}">
		<table border="1">

			<tr>
				<th>id</th>
				<td><div th:text="*{id}"></div></td>
			</tr>
			<tr>
				<th>やること</th>
				<td><div ><div th:text="*{task}"></div></div></td>
			</tr>

		</table>
	</div>

</body>
</html>
```
todoの中身のidとtaskを表示します。

# 2-4.change.html(変更画面)
```html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
	xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
	layout:decorator="layout">
<meta charset="UTF-8">
<title>ToDo変更</title>

</head>
<body>

	<h2>ToDo変更</h2>

	<form th:action="@{/todos/put/{id}(id=*{id})}" th:method="put"
		th:object="${todo}">
		<!-- 入力したやつをtodoの中にいれて使える -->

		<ul>
			<li><label>やること</label> <br> <input type="text" id="todo"
				name="todo" th:field="*{task}" /> <!-- fieldはramen.shopとかにしてHTMLで使える -->
		</ul>
		<button>更新</button>

	</form>
</body>
</html>
```
todoの中身を入れ替えます。ほぼnew.htmlと同様です。
>th:action="@{/todos/put/{id}(id=*{id})}" th:method="put" th:object="${todo}"

taskを詰め直したtodoをcontrollerの/todos/put/{id}(id=*{id})に渡します。
URLが該当のidになるようにしているので、{id}(id=*{id}となっています。
deleteと同じく、Controllerの`@@PutMapping`に対応します。



残りは次の記事へ
https://qiita.com/sumichan/items/a53e223c2a727cae26a4