[KPI] javaで簡易todoリストを作成する

#簡単な流れ
１、テーブル作成
２、サーブレット作成
３、jsp作成

#テーブル作成
用途は、name（タスク）を一覧表示、登録・更新・削除を行う。
id             :　オートインクリメントするように。
name           : ３０文字までは可能。
created,updated: タイムスタンプで、デフォルトで現在日時が入るように。

```
create table todos(
  id serial, 
  name varchar(30),
  created timestamp default now(),
  updated timestamp default now()
)
```

#サーブレット作成
下記ソースに直接説明を書いていく。

```java
package controller;

import java.io.IOException;
import java.sql.Connection; データベースと接続するために必要
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;　配列を使用するために必要
import java.util.HashMap;　連想配列を使用するために必要。　

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ServeletReservation
 */
@WebServlet("/ServeletTodo")　左記がurlになる。　例えば、プロジェクト名/ServeletTodoとなる
public class ServeletReservation extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public ServeletTodo() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException { get送信された際に、このメソッドが走る
		// TODO Auto-generated method stub

		Connection conn = null;
		Statement stmt = null;
		ResultSet rset = null;

		try {
			//PostgreSQLへ接続
			conn = connectDB();

			//自動コミットOFF
			conn.setAutoCommit(false);

			//SELECT文の実行
			stmt = conn.createStatement();
			String sql = "select * from todos";　一覧表示するためのリストを取得する
			ArrayList<HashMap> todoList = new ArrayList<>();　配列作成 <>の中には、型を入れる
		    rset = stmt.executeQuery(sql);

			//SELECT結果の受け取り
			while (rset.next()) {rset.next()がtrueの間はループする。これで全レコード取得
				HashMap<String, String> hmap = new HashMap<String, String>();　キー：文字列　値：文字列の連想配列作成
				String id = rset.getString("id");　DBからidカラムの値を取得
				String task = rset.getString("name");　DBからnameカラムの値を取得
				hmap.put("id", id);　上記で取得した値を連想配列のキーにセット
				hmap.put("task", task);　上記で取得した値を連想配列の値にセット　これで、{'1', '英語学習'}のような連想配列が完成
				todoList.add(hmap);　連想配列を配列に格納。　これをjspにて、forEachで一覧表示
			}
			request.setAttribute("todos", todoList);　todosというキーで上記で作成した配列を値としてセット。呼び出す時は、request.getAttribute("todos");とすることで可能
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {　try・catchが成功しても失敗してもここの処理に入る
			try {
				if (rset != null)
					rset.close();
				if (stmt != null)
					stmt.close();
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}

		}
		RequestDispatcher dispatch = request.getRequestDispatcher("index.jsp");
		dispatch.forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {post送信の時はここの処理に入る
		// TODO Auto-generated method stub
		String method = request.getParameter("method");

		//		追加
		if (method.equals("POST")) {
			String task = request.getParameter("task");
			doPost(task);
		}

		//		更新
		if (method.equals("PUT")) {
			String id = request.getParameter("id");
			Integer idInt = Integer.parseInt(id);
			String task = request.getParameter("task");
			doPut(idInt, task);
		}

		//		削除
		if (method.equals("DELETE")) {
			String id = request.getParameter("id");
			Integer idInt = Integer.parseInt(id);
			doDelete(idInt);

		}

		doGet(request, response);
	}

	public void doPost(String task) {

		String sql = "insert into todos(name) values (?)"; sql作成

		try {
			Connection conn = connectDB();

			PreparedStatement stmt = conn.prepareStatement(sql, java.sql.Statement.RETURN_GENERATED_KEYS);

			stmt.setString(1, task);　上記sqlの❔部分に第二引数を当てはめる。ちなみに、第一引数は左から数えての❔の順番
			stmt.executeUpdate();

		} catch (SQLException e) {
			System.out.print("SQLException:" + e.getMessage());
		}
	}

	public void doPut(Integer id, String task) {

		String sql = "update todos set name = ? where id = ?";

		try {
			Connection conn = connectDB();

			PreparedStatement stmt = conn.prepareStatement(sql, java.sql.Statement.RETURN_GENERATED_KEYS);

			stmt.setString(1, task);
			stmt.setInt(2, id);
			stmt.executeUpdate();

		} catch (SQLException e) {
			System.out.print("SQLException:" + e.getMessage());
		}
	}

	public void doDelete(Integer id) {

		String sql = "delete from todos where id = ?";

		try {
			Connection conn = connectDB();

			PreparedStatement stmt = conn.prepareStatement(sql, java.sql.Statement.RETURN_GENERATED_KEYS);

			stmt.setInt(1, id);
			stmt.executeUpdate();

		} catch (SQLException e) {
			System.out.print("SQLException:" + e.getMessage());
		}
	}

	public Connection connectDB() throws SQLException {

		//接続文字列
		String url = "jdbc:postgresql://localhost:5432/test";
		String user = "postgres";
		String password = "test1212";

		Connection conn = DriverManager.getConnection(url, user, password);
		return conn;

	}
}

```

#jsp作成
```jsp
<%@ page contentType="text/html; charset=Shift_JIS" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> forEachが使えるように導入
<%@ page isELIgnored="false"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>todo</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport"
	content="width=device-width, initial-scale=1, shrink-to-fit=no">

<!-- Bootstrap CSS -->
<link rel="stylesheet"
	href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
	integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"
	crossorigin="anonymous">
</head>
<body>

	<div class="container mx-auto">
		<h1 class="text-center mb-4">todoリスト</h1>
		<div class="mx-auto w-25">
			<!-- タスク追加欄 -->
			<div class="d-flex mb-4">
				<div>
					<input type="text" id="js-task">
				</div>
				<div style="margin-left: auto;">
					<button id="js-add-task" class="ml-3">追加</button>
				</div>
			</div>
			<c:forEach var="todo" items="${todos}">request.setAttributeでセットしたキーをitemsに入れる。var="todo"配列の一つ一つの値が入っている
				<div class="d-flex mb-3">
					<div>
						<input class="js-edit-task" type="text" value="${todo.task}"
							data-id="${todo.id}" />
					</div>
					<div style="margin-left: auto;">
						<button class="js-delete-task" data-id="${todo.id}">削除</button>
					</div>
				</div>
			</c:forEach>
		</div>
	</div>
	<div id="modal-overlay"></div>

	<!-- Optional JavaScript -->
	<!-- jQuery first, then Popper.js, then Bootstrap JS -->
	<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
	<script
		src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"
		integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
		crossorigin="anonymous"></script>
	<script
		src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"
		integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy"
		crossorigin="anonymous"></script>

	<script>
	　　/* タスク登録 */
		$('#js-add-task').click(function() {
			var task = $('#js-task').val();

			$.ajax({
				url: './ServeletReservation',
				type: 'POST',
				data:{task: task, method: "POST"},
			    success: function(response) {
	            	alert("success");
	            	location.reload();
	           	},
				error: function(response) {
					alert("error");
				}
			});
		})

		/* タスク更新 */
		$('.js-edit-task').change(function() {
			var task = $(this).val();
			var id = $(this).data().id;

			$.ajax({
				url: './ServeletReservation',
				type: 'POST',
				data:{task: task, id: id, method: "PUT"},
			    success: function(response) {
	            	alert("success");
	            	location.reload();
	           	},
				error: function(response) {
					alert("error");
				}
			});
		});

		/* タスク削除 */
		$('.js-delete-task').click(function() {
			var id = $(this).data().id;

			$.ajax({
				url: './ServeletReservation',
				type: 'POST',
				data:{id: id, method: "DELETE"},
			    success: function(response) {
	            	alert("success");
	            	location.reload();
	           	},
				error: function(response) {
					alert("error");
				}
			});
		});

	</script>
</body>
</html>
```

#終わりに
著者は、サーバーサイド言語はphpしか経験がなかったので、javaを使用してwebサービスを作成することは非常に勉強になった。
具体的には、下記の点である
１、細かい違いはあれど、根幹の仕組みは、phpもjavaでも同じであり、根幹の仕組みさえ理解しておけばどの言語も習得可能であることが理解できるということ。
２、javaは、変数宣言の際に、型宣言が必要であったり、db接続の際などいちいちクラスをインポートしてメソッドを使わないといけないので、phpが比較的楽にコーディングできるということ。

これだけだとjavaのことはなにもわかっていない状態同然だと思うので、まだまだ理解を深めていきたいと思うし、
扱える言語を一つずつ増やしていきたいと思う。