【Java: Todoアプリ】Todoを編集する

今回の記事はこちらの記事の続きとなっております。

現在Java(サーブレット・jsp) x PostgreSQLを使ってTodoアプリを作成しています。現時点での機能は次のとおりです。

今回は上記に加えてTodoの編集を行えるようにしていきます。今回作成する編集機能は次のような流れにします。

  • 一覧から「Todoを編集する」ボタンをクリックしたら編集画面に遷移
  • 編集画面にはすでに入力されているデータが入っている上で編集をすることができる
  • 編集が終了し、「Todoを更新する」を押すとデータベースに編集内容が反映される
  • 一覧表示するとTodoの内容が更新されている

順番に作っていきます。

その他の機能はこちらにまとめています。

ご質問等あればこちらのTwitterアカウントまでお願いします。

Java x MySQLでWebアプリの作り方が学べるUdemy講座

list.jspの変更

まずは一覧から編集画面に遷移するためにlist.jspを編集します。考慮する点は次の2点です。

  • Todoを取得するためにTodoのIDをサーバーに送る必要がある
  • 「Todoを更新する」を押したら更新画面に遷移する

今回はlist.jspにaタグを設置します。リンクで更新処理をするサーブレットにリクエストを送ります。その際にリクエストパラメータとしてTodoのIDを送るようにします。リンクで送られるリクエストは基本的にGETメソッドです。GETメソッド時はURLに記述することでパラメータを送ることができます。

現在for文を使ってTodoを表示していますが、その中身を次のように変更します。

<h5><%=todo.getTodo()%></h5>
<h6><%=todo.getTimeLimit()%></h6>
<a href="update-servlet?<%=Parameters.TODO_ID %>=<%= todo.getId() %>">todoを更新する</a>

重要なのはaタグのhref属性です。最初の「update-servlet」はリクエストを送りたいサーブレットのパスです。これは後ほど作成します。

次に「?<%=Parameters.TODO_ID %>=<%= todo.getId() %>」となっているところです。GETでリクエストを送るときは「?x=y」とすることでキーがx、値がyという情報をサーバー側に送ることができます。今回はまず前回作成したパラメータ名をstatic変数で準備したクラスを使ってtodoIdというキーで値を送ります。実際に送られる値が「todo.getId()」によって取得できる値になります。

この変更によって一覧画面に「todoを更新する」リンクが表示され、それをクリックすると更新したいTodoのidがサーバー側に送られるという事になります。

次にそのリクエストを受け取るサーバー側の処理を記述していきます。

 

UpdateDAOの作成

まずは更新機能でデータベースに接続する際に利用するUpdateDAOクラスをmodelパッケージ内に作成します。更新機能でデータベースに接続したいのは「更新するTodoを取得する」処理と「実際にTodoを更新する」処理が必要です。まずは「更新するTodoを取得する」メソッドを作成します。中身は次のようになります。

package model;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import model.dao.dto.TodoDTO;

// Todoの更新を行うクラス
public class UpdateDAO {

	/**
	 * idを元にデータベースからTodo情報を取得する
	 * @param id
	 * @return todo
	 * @throws SQLException
	 * @throws ClassNotFoundException
	 */
	public TodoDTO getTodo(int id) throws SQLException, ClassNotFoundException {
		// 取得したTodoを格納する変数
		TodoDTO todo = new TodoDTO();

		// Idを指定してTodoを取得するSQL
		String sql = "SELECT id, todo, timeLimit FROM todo where id = ? ";

		// DBに接続し、Todoを取得する
		try (Connection con = DBConnection.getConnection();
				PreparedStatement pstmt = con.prepareStatement(sql);) {

			pstmt.setInt(1, id);

			// SQLを実行しTodoを取得する
			ResultSet res = pstmt.executeQuery();

			while(res.next()) {
				// DBから取得したTodoの情報をtodoに持たせる
				todo.setId(res.getInt("id"));
				todo.setTodo(res.getString("todo"));
				todo.setTimeLimit(res.getDate("timeLimit"));
			}
		}

		return todo;

	}
}

大切なのはgetTodoメソッドです。更新するTodoのidを受け取り、それを元にデータベースからTodoのデータを取得します。getTodoメソッドの中身を見ていきます。まずは実行するSQL文を作成しています。最後の「?」の中に引数で受け取ったidを設定します。

// Idを指定してTodoを取得するSQL
String sql = "SELECT id, todo, timeLimit FROM todo where id = ? ";

次に実際にSQLを実行しTodoの情報を取得します。最初にSQLにIdを設定します。その後executeQueryメソッドでSQLを実行します。取得したTodoの情報をtodoDTOに設定して値を持たせます。

// DBに接続し、Todoを取得する
try (Connection con = DBConnection.getConnection();
		PreparedStatement pstmt = con.prepareStatement(sql);) {

	pstmt.setInt(1, id);

	// SQLを実行しTodoを取得する
	ResultSet res = pstmt.executeQuery();

	while(res.next()) {
		// DBから取得したTodoの情報をtodoに持たせる
		todo.setId(res.getInt("id"));
		todo.setTodo(res.getString("todo"));
		todo.setTimeLimit(res.getDate("timeLimit"));
	}
}

これでidを元に更新対象となるTodoのデータを取得することができます。

 

UpdateServletの作成

次にサーブレットを作成します。servletパッケージの中にUpdateServlet.javaを作成します。パスは次のように設定します。

@WebServlet("/update-servlet")

一覧画面からaタグのリンクを使ってリクエストが送られてきます。これはGETメソッドでのリクエストなのでサーブレット内のdoGetメソッドを編集します。

/**
 * リクエストパラメータから送られてきたTodoのIDをもとにDBからデータを取得し、画面に表示する
 */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	// リクエストパラメータからtodoIdを取得する
	int todoId = Integer.parseInt(request.getParameter(Parameters.TODO_ID));

	UpdateDAO dao = new UpdateDAO();
	TodoDTO todo = new TodoDTO();
	try {
		// todoの取得
		todo = dao.getTodo(todoId);
	} catch (SQLException | ClassNotFoundException e ) {
		e.printStackTrace();
	}

	request.setAttribute("todo", todo);
	request.getRequestDispatcher("update.jsp").forward(request, response);
}

最初にリクエストパラメータからTodoのIdを取得します。取得する際にはParametersクラスのstatic変数を使っています。

// リクエストパラメータからtodoIdを取得する
int todoId = Integer.parseInt(request.getParameter(Parameters.TODO_ID)

Todo情報を取得するための変数宣言です。先程作したUpdateDAOとTodoDTOをインスタンス化しておきます。

UpdateDAO dao = new UpdateDAO();
TodoDTO todo = new TodoDTO();

上記で宣言した変数を使ってデータベースに接続してTodo情報を取得します。

try {
	// todoの取得
	todo = dao.getTodo(todoId);
} catch (SQLException | ClassNotFoundException e ) {
	e.printStackTrace();
}

取得したTodoの情報をリクエストスコープに設定します。リクエストスコープに関してはQiitaにまとまった記事があるので時間がある方は読んでみると理解が深まります。

そしてupdate.jspに画面遷移します。

request.setAttribute("todo", todo);
request.getRequestDispatcher("update.jsp").forward(request, response);

 

update.jsp

Todoを編集する画面であるupdate.jspを作成します。全体は以下のようになります。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="model.dao.dto.TodoDTO" %>
<%@ page import="constant.Parameters" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<%
TodoDTO todo = (TodoDTO)request.getAttribute("todo");
%>
<body>
<form action="update-servlet" method="post" >
	<label>Todo: </label><input type="text" name="<%=Parameters.TODO %>" value="<%=todo.getTodo()%>"><br>
	<label>Limit: </label><input type="date" name="<%=Parameters.TIME_LIMIT %>" value="<%=todo.getTimeLimit()%>"> <br>
	<input type="hidden" name="<%=Parameters.TODO_ID %>" value="<%=todo.getId() %>">
	<input type="submit" value="Todoを更新する">
</form>

</body>
</html>

まずUpdateServlet内でリクエストスコープに設定したtodo情報を取得します。

<%
TodoDTO todo = (TodoDTO)request.getAttribute("todo");
%>

更新するTodoを画面に表示するのが以下の箇所です。大切なのは上二つのinputタグの中です。

<form action="update-servlet" method="post" >
	<label>Todo: </label><input type="text" name="<%=Parameters.TODO %>" value="<%=todo.getTodo()%>"><br>
	<label>Limit: </label><input type="date" name="<%=Parameters.TIME_LIMIT %>" value="<%=todo.getTimeLimit()%>"> <br>
	<input type="hidden" name="<%=Parameters.TODO_ID %>" value="<%=todo.getId() %>">
	<input type="submit" value="Todoを更新する">
</form>

既存の情報を入力された状態で表示したいのでinputタグのvalue属性にtodoの情報を入れています。また更新する際にサーバー側にデータを送りたいのでname属性の中をParametersクラスのstatic変数を使って名前を決めています。

<input type="text" name="<%=Parameters.TODO %>" value="<%=todo.getTodo()%>">
<input type="date" name="<%=Parameters.TIME_LIMIT %>" value="<%=todo.getTimeLimit()%>">

 

動作確認

一旦ここまでで動作確認してみます。サーバーを立ち上げ一覧画面を表示します。一部切り取っていますが、下記のような画面が表示されていれば良いです。「todoを更新する」リンクがあることを確認しましょう

「todoを更新する」リンクを押してみます。今回は「create todo app」「2021-06-30」のTodoのリンクを押してみます。すると以下の画面のように既存のデータが入力された状態の入力画面が表示されます。

次回予告

ちょっと長くなりそうなので、実際にTodoを更新する部分は次の記事に回します。

ご質問等あればこちらのTwitterアカウントまでお願いします。

私はプログラミング学習はUdemyで行うのが以下のような理由で圧倒的におすすめです。

  • 動画で好きなときに学べる
  • 一流のエンジニアから教えてもらえる
  • 好きな技術を体系的に学べる
  • 実際に手を動かしながら学ぶことができる
  • セール時であれば1500円〜2000円ほどで購入できる(大半の技術書より安い)
  • 講座自体がアップデートされていくので情報が古くなりにくい

UdemyにはJava x MySQLでWebアプリの作り方が学べるUdemy講座 もあるので興味がある方は一度チェックしてみてください!なおUdemyは頻繁にセールをやっているので、セール時を狙って購入してください!

おすすめの参考書

コメント

タイトルとURLをコピーしました