Java・ツイッタークローン・タスク管理システム⑥削除機能をつける

##はじめに
Javaを使って初めてアプリケーションを作成する人にむけて記事を書いてみようと思います。
ポートフォリオや、会社の研修課題作成の参考にしていただければ幸いです。
今回は、タスクマネージャーを作成します。
これを応用することで、ツイッタークローンの作成にも活かすことができます。

アプリケーションの機能ごとに記事を投稿していきます。
1.データベース作成
2.ログイン機能
3.タスクの登録機能
4.一覧表示
　　-ソート機能
　　-検索機能
5.編集機能
6.削除機能
7.排他制御について

＊詳しい説明はコード内に書いてありますので、コピペする人は消して使ってください

##実行環境
eclipse4.16.0
Tomcat9
Java11
Mysql5.7

目次
1.viewの作成
2.DAOの作成
3.サーブレット作成
4.次回予告

#viewの作成

タスクの削除前にここでタスクの詳細の確認をしてもらう

```task-delete.java
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>タスク削除</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
</head>
<body>
<jsp:useBean id="task" scope="request" class="model.entity.TaskBean"/>
<%
String category_name = (String)request.getAttribute("category_name");
String status_name = (String)request.getAttribute("status_name");
String user_name = (String)request.getAttribute("user_name");
int version = (int)request.getAttribute("version");
%>
	<jsp:include page="header.jsp"/>
	<div class="contain mt-4 mr-5 ml-5">
		<div class="row justify-content-center">
			<h3>タスク削除</h3>
		</div>
		<table class="table">
		  <thead>
		    <tr>
		      <th scope="col"></th>
		      <th scope="col">このタスクを削除しますか？</th>
		    </tr>
		  </thead>
		  <tbody>
		  <tr>
		      <th scope="row">タスクID</th>
		      <td><jsp:getProperty property="task_id" name="task"/></td>
		    </tr>
		    <tr>
		      <th scope="row">タスク名</th>
		      <td><jsp:getProperty property="task_name" name="task"/></td>
		    </tr>
		    <tr>
		      <th scope="row">カテゴリー</th>
		      <td><jsp:getProperty property="category_id" name="task"/>：<%=category_name %></td>
		    </tr>
		    <tr>
		      <th scope="row">期限</th>
		      <td><jsp:getProperty property="limit_date" name="task"/></td>
		    </tr>
		    <tr>
		      <th scope="row">ユーザ名</th>
		      <td><%=user_name %></td>
		    </tr>
		    <tr>
		      <th scope="row">ステータス</th>
		      <td><jsp:getProperty property="status_code" name="task"/>：<%=status_name %></td>
		    </tr>
		    <tr>
		      <th scope="row">メモ</th>
		      <td><jsp:getProperty property="memo" name="task"/></td>
		    </tr>
		    <tr>
		      <th scope="row">登録日時</th>
		      <td><jsp:getProperty property="create_datetime" name="task"/></td>
		    </tr>
		    <tr>
		      <th scope="row">更新日時</th>
		      <td><jsp:getProperty property="update_datetime" name="task"/></td>
		    </tr>
		  </tbody>
		</table>
		<form action="task-delete-servlet" method="post">
			<input type="hidden" name="task_id" value="<jsp:getProperty property="task_id" name="task"/>">
			<input type="hidden" name="version" value="<%=version %>">
			<button type="submit" class="btn btn-outline-danger">削除</button>
		</form>
	</div>

<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</body>
</html>
```

タスクが無事削除できたらこの画面にて確認してもらう。

```task-delete-comp.java
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>削除完了</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/task-edit-failure.css">
<body>
	<jsp:include page="header.jsp"/>
	<div class="contain">
		<div class="box">
			 <h3>タスクの削除が完了しました</h3>
		</div>
	</div>
</body>
</html>
```

タスクの削除に失敗したらこの画面を表示
（次回行う排他制御などなんらかの理由で削除できなかった時にはこちらでお知らせする）

```task-delete-failure.java
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>タスクの削除失敗</title>
<link rel="stylesheet" href="${pageContext.request.contextPath}/task-edit-failure.css">
</head>
<body>
<jsp:include page="header.jsp"/>
	<div class="contain">
		<div class="box">
		  <h3>タスクの削除に失敗しました</h3>
		</div>
	</div>
</body>
</html>
```

#DAOの作成
こちらでは前回作成したタスク編集記事に出てくるメソッドも出てきます。
必要な方だけみてください

```model.dao.TaskDAO.java
/**
	 * task_idを引数に特定のタスクを取得する
	 * @param task_id
	 * @return
	 * @throws SQLException
	 * @throws ClassNotFoundException
	 */
	public TaskBean getSpecificTask(int task_id) throws SQLException, ClassNotFoundException {
		 TaskBean task = new TaskBean();
		 String sql = "select * from t_task where task_id = ?";
		 try(Connection con = ConnectionManager.getConnection();
				 PreparedStatement pstmt = con.prepareStatement(sql);){
			 pstmt.setInt(1, task_id);
			 ResultSet res = pstmt.executeQuery();
			 //taskオブジェクトへカラム情報を格納していく
			 while(res.next()) {
				task.setTask_id(task_id);
				task.setTask_name(res.getString("task_name"));
				task.setCategory_id(res.getInt("category_id"));
				task.setLimit_date(res.getDate("limit_date"));
				task.setUser_id(res.getString("user_id"));
				task.setStatus_code(res.getString("status_code"));
				task.setMemo(res.getString("memo"));
				task.setCreate_datetime(res.getTimestamp("create_datetime"));
				task.setUpdate_datetime(res.getTimestamp("update_datetime"));
				task.setVersion(res.getInt("version"));
			 }
		 }
		 return task;
	 }

/**
	  * タスク削除用メソッド
	  * @param task_id
	  * @return sum
	  * @throws SQLException
	  * @throws ClassNotFoundException
	  */
	 public int deleteTask(int task_id) throws SQLException, ClassNotFoundException {
		 String sql = "delete from t_task where task_id = ?";
		 int sum = 0;
			 try(Connection con = ConnectionManager.getConnection();
			 PreparedStatement pstmt = con.prepareStatement(sql)){
				 pstmt.setInt(1, task_id);
				 sum = pstmt.executeUpdate();
		 }
		 return sum;
	 }
```

#サーブレット作成
こちらで、タスク一覧画面から選択したタスクの情報を取得してセッションスコープへ入れて、確認画面へ転送する

```servlet.TaskDeleteDetailServlet.java
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub

		TaskDAO taskdao = new TaskDAO();
		TaskBean task = new TaskBean();
		CategoryDAO categorydao = new CategoryDAO();
		StatusDAO statusdao = new StatusDAO();
		UserDAO userdao = new UserDAO();

		//リクエストパラメータ取得
		request.setCharacterEncoding("UTF-8");
		int task_id = Integer.parseInt(request.getParameter("task_id"));

		try {
			task = taskdao.getSpecificTask(task_id);
			int category_id = task.getCategory_id();
			String status_code = task.getStatus_code();
			String user_id = task.getUser_id();
			String category_name = categorydao.getCategoryName(category_id);
			String status_name = statusdao.getStatusName(status_code);
			String user_name = userdao.getUserName(user_id);
			int version = task.getVersion();
			request.setAttribute("task", task);
			request.setAttribute("category_name", category_name);
			request.setAttribute("status_name", status_name);
			request.setAttribute("user_name", user_name);
			request.setAttribute("version", version);

		}catch(SQLException | ClassNotFoundException e) {
			e.printStackTrace();
		}
		RequestDispatcher rd = request.getRequestDispatcher("task-delete.jsp");
		rd.forward(request, response);
	}
```

```servlet.TaskDeleteServlet.java
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//リクエストパラメータ取得
		request.setCharacterEncoding("UTF-8");
		int task_id = Integer.parseInt(request.getParameter("task_id"));
		int version =  Integer.parseInt(request.getParameter("version"));
		TaskDAO taskdao = new TaskDAO();

		List<String> error = new ArrayList<String>();


		try{
			//versionの確認
			int current_version = taskdao.getVersion(task_id);
			if(current_version != version) {
				error.add("このタスクは他の人によって上書きがされています");
				request.setAttribute("error", error);
				RequestDispatcher rd = request.getRequestDispatcher("task-update-failure.jsp");
				rd.forward(request, response);
			}

			//タスクの削除実行
			taskdao.deleteTask(task_id);
			RequestDispatcher rd = request.getRequestDispatcher("task-delete-comp.jsp");
			rd.forward(request, response);
		} catch(SQLException | ClassNotFoundException e) {
			RequestDispatcher rd = request.getRequestDispatcher("task-delete-failure.jsp");
			rd.forward(request, response);
		}
	}

```

#次回予告
今回は削除機能の実装をしてきました。
初めてのアプリケーションに最低限の機能はここまでの記事にあるコードを使えばできます。
次回は、排他制御と言う複数のユーザが同時にアプリケーションを使うことを考えた時の処理について紹介してまいります。