🐡

Servlet、JSP、Java、MVCパタンにJDBCを適応したDB連携~CRUDのU(Update)とD(Delete)例文

2023/09/22に公開

前書き

今回も、前回から続けてWEBページとDBを連携する例文をまとめる。今回はC(Create)とR(Read)の後にできる、U(Update)とD(Delete)である。CreateとReadよりは比較てき重要度が低いとも言えるが、重要ではないと言って、知っているか知ってないか、コードを作れるか作れないかは別問題であるので、2つを合わせてCRUDを最後にまとめようと思っている。

ページ上で今回まとめる内容を見てみよう。とりあえずページ上での修正ながれである。

次は、ページ上でデータを削除する流れである。

コードの前に、簡単なプログラムの流れ

今回のコードは、上記した流れのコードからまとめようと思う。前回と前々回のまとめで省略する部分のコードをまとめておいたので、あのまとめを参考しよう。

まじはUpdateの法から流れをまとめる。

次はDeleteの流れをまとめる。

Updateのコードまとめ

まずは、今回のまとめで1番最初に当たる「appleoutput.jsp」である。UpdateとDeleteに当たらないコードには注釈を最小限に付ける。

appleoutput.jsp

<%@page import="com.inchel.Sep141.apple.AppleDTO"%>
<%@page import="java.util.ArrayList"%>
<%@ taglib prefix= "c" uri= "http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix= "fmt" uri = "http://java.sun.com/jsp/jstl/fmt" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

	<hr>

	여기는 AppleDB <br>
	DB 연결 결과 : ${result}<p><p>
	
	<%
	   <!--DBからデータを読み込んで、それをArrayListに貯蔵したものを持ってくる。 -->
		ArrayList<AppleDTO> aList = (ArrayList<AppleDTO>)request.getAttribute("alist");
	<!--持ってきたデータの地域をパラメータにして、クリックすると情報を見れるように<a> タグでAppleControllerに移動させる。-->
		for(int i = 0; i < aList.size(); i++){
	%>
	<!-- 各データ項目をクリックすると、詳細情報が見れる「AppleInfoControlle」に移動する。-->
		<div> <a href = "AppleInfoController?getinfolocation=<%=aList.get(i).getLocation()%>"> 
		地域 : <%=aList.get(i).getLocation() %> 値段: <%=aList.get(i).getPrice() %>
		</a>
		</div>
		 <p><p>
	<% 	
		}
	%>
	<hr>
	<jsp:include page = "pages.jsp" />
	<hr>
	<div> <a href = "appleregister.jsp"> データ登録ページに移動 </a> </div>
	<hr>
</body>
</html>

次は、各データ項目の詳細情報を持ってきて、「appleinfo.jsp」に移動してくれる「AppleInfoController」Servletになる。

AppleInfoController.java

package com.inchel.Sep141.apple;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/AppleInfoController")
public class AppleInfoController extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//項目をクリックしたときのパラメータを持って、DBで情報が見つかれたら
		if(AppleDB.getAppledb().getAppleInfo(request)) {
		//詳細情報を見せる「appleinfo.jsp」をAttributeに入れる。
		request.setAttribute("cp", "appleinfo.jsp");
		request.getRequestDispatcher("index.jsp").forward(request, response);
		//DBで情報が見つかれなかったら
		} else {
		//詳細情報が見られないにで、「appleoutput.jsp」に戻る。
		request.setAttribute("cp", "appleoutput.jsp");
		request.getRequestDispatcher("index.jsp").forward(request, response);
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	
	}

}


次は、上のServletにあった、クリックした項目のデータだけを持ってくる「getAppleInfo」メソッドになる。

getAppleInfo.java
public boolean getAppleInfo(HttpServletRequest request) {
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try{
		con = InchelDBManager.connect("inchelPool");
		//各データ項目に与えたパラメータ「getinfolocation」nameのデータを利用して、クリックした項目のデータだけを持ってくる。
		String getLocation = request.getParameter("getinfolocation");
		request.setAttribute("deletelocation", request.getParameter("getinfolocation"));
		String sql = "SELECT * FROM sep14_apple WHERE a_location = '" + getLocation +"'";
		pstmt = con.prepareStatement(sql);
		rs = pstmt.executeQuery();
			
		AppleDTO a = null;
		
		//DBで持ってきたデータを、DTOのインスタンスに作ってAttributeに入れる。
		while(rs.next()) {
			a = new AppleDTO();
			a.setLocation(rs.getString("a_location"));
			a.setColor(rs.getString("a_color"));
			a.setTaste(rs.getString("a_taste"));
			a.setPrice(rs.getInt("a_price"));
			a.setIntroduce(rs.getString("a_introduce"));
			request.setAttribute("info", a);
			return true;
		}
		return false; //
				
		} catch(Exception e){
			e.printStackTrace();
			return false; //
		}
		  finally {
		InchelDBManager.close(con, pstmt, rs);
		 }
	}

次は、上の「getAppleInfo」メソッドで持ってきたデータの詳細情報を見せる「appleinfo.jsp」になる。ここのページで修正のページに移動できる。

appleinfo.jsp

<%@page import="com.inchel.Sep141.apple.AppleDTO"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type = "text/javascript" src = "deletecheck.js"> </script>
</head>
<body>
	<p><p>
	<!--「getAppleInfo」メソッドで持ってきたデータをここで出力する。-->
	<!-- 同時に、ここで修正するデータの内容を入力する。-->
	<!-- 各Inputには基本的に既存のデータが入力されるようにして、修正をしないデータは既存のままでDBに入る。-->
	<%AppleDTO a = (AppleDTO)request.getAttribute("info"); %>
	<form action = "AppleUpdateController" method = "post">
	<div> 地域 : <input name = "updatelocation" value = "<%=a.getLocation()%>" readonly = "true"></div><p>
	<div> 色 : <input name = "updatecolor" value = "<%=a.getColor()%>" ></div><p>
	<div> 味 : <input name = "updatetaste" value = "<%=a.getTaste()%>" ></div><p>
	<div> 値段 : <input name = "updateprice" value = "<%=a.getPrice()%>" ></div><p>
	<div> 説明 : <input name = "updateintroduce" value = "<%=a.getIntroduce()%>" ></div><p>
	<p>
	
	<!-- 「修正」ボタンを押すと、上のinputのデータを持って「AppleUpdateController.java」Servletに移動する。 -->
	<div><button> 修正 </button> </div>
	</form>
	
	<button onclick = "deleteApple('${deletelocation}')">
	 削除
	</button>

</body>
</html>

次は、修正するデータを入力して「修正」ボタンを押したとき実行される「AppleUpdateController.java」Servletになる。

AppleUpdateController.java

package com.inchel.Sep141.apple;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/AppleUpdateController")
public class AppleUpdateController extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//データを修正した後、ページ数を数えてデータを再び更新する。
		AppleDB.getAppledb().updateAppleDB(request);
		AppleDB.getAppledb().getPageCount(request);
		AppleDB.getAppledb().getAppleDB(request);
		//データを更新したあと、「appleoutput.jsp」に戻る。
		request.setAttribute("cp", "appleoutput.jsp");
		request.getRequestDispatcher("index.jsp").forward(request, response);
	}

}

次は、修正コードまとめの最後になる、実際にDBに接続してデータを変更(Update)する「updateAppleDB」メソッドになる。これは「AppleDB.java」DAOにある。修正を担当するところだけをまとめる。

AppleDB.java
	Connection con = null;
	PreparedStatement pstmt = null;
		
		try {
		con = InchelDBManager.connect("inchelPool");
		
		//Servletの「doPost」メソッドでこのメソッドを実行すると、下のコードを入力する。もらったデータを"UTF-8"に変換。
		request.setCharacterEncoding("UTF-8"); 
		//SQL文を作成。「appleinfo.jsp」の修正フィールドで送ったデータをここで使う。
		//SQL文の内容(下の「pstmt.set~~~」まで見るべき)は下記のようである。
		//詳細情報の地域の値を持っている項目のデータをUpdate(変更)する。
		String sql = "update sep14_apple set "
	               + "a_color=?, a_taste=?, a_price=?, a_introduce=? "
	               + "where a_location =?";
		System.out.println(sql);
		pstmt = con.prepareStatement(sql);
		pstmt.setString(1, request.getParameter("updatecolor"));
		pstmt.setString(2, request.getParameter("updatetaste"));
		pstmt.setInt(3, Integer.parseInt(request.getParameter("updateprice")));
		pstmt.setString(4,request.getParameter("updateintroduce"));
		pstmt.setString(5,request.getParameter("updatelocation"));
		
		//上のSQL文がうまく作動して、DBにデータが変更されたら
		if(pstmt.executeUpdate() == 1) {
			System.out.println("DB修正に成功しました。");
			return true;
		} else {
			System.out.println("DB修正に失敗しました。");
			return false;
		}
		
	} catch(Exception e) {
		e.printStackTrace();
		return false;
	} finally {
		InchelDBManager.close(con, pstmt, null);
	}


Deleteのコードまとめ

Deleteをするコードは、削除をするに至る前の被るコードを省略して、Deleteを担当するコードだけをまとめる。

まずは、「削除」ボタンがある「appleinfo.jsp」になる。Updateコードのまとめにもうあるファイルであるので、注釈なしですぐ次に行く。

appleinfo.jsp

```html:appleinfo.jsp
<%@page import="com.inchel.Sep141.apple.AppleDTO"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type = "text/javascript" src = "deletecheck.js"> </script>
</head>
<body>
        <p><p>
        <!--「getAppleInfo」メソッドで持ってきたデータをここで出力する。-->
        <!-- どうじに、ここで修正するデータの内容を入力する。-->
        <!-- 各Inputには基本的に既存のデータが入力されるようにして、修正をしないデータは既存のままでDBに入る。-->
        <%AppleDTO a = (AppleDTO)request.getAttribute("info"); %>
        <form action = "AppleUpdateController" method = "post">
        <div> 地域 : <input name = "updatelocation" value = "<%=a.getLocation()%>" readonly = "true"></div><p>
        <div> 色 : <input name = "updatecolor" value = "<%=a.getColor()%>" ></div><p>
        <div> 味 : <input name = "updatetaste" value = "<%=a.getTaste()%>" ></div><p>
        <div> 値段 : <input name = "updateprice" value = "<%=a.getPrice()%>" ></div><p>
        <div> 説明 : <input name = "updateintroduce" value = "<%=a.getIntroduce()%>" ></div><p>
        <p>
        
        <!-- 「修正」ボタンを押すと、上のinputのデータを持って「AppleUpdateController.java」Servletに移動する。 -->
        <div><button> 修正 </button> </div>
        </form>
        
	//下のボタンを押して、削除を実行する前に確認のメッセージを出して、そのあとServletに移動する「deletecheck.js」になる。
	//今回はformでページの移動ができないであるし、削除を確認するためにjsを使う。
	//onclick = "関数名(パラメータ)" 形式で、ボタンを押したとき関数を実行できる。
	//パラメータには、項目のデータをもらうときに、「deletelocation」nameで貯蔵した地域の名前を使う。
        <button onclick = "deleteApple('${deletelocation}')">
         削除
        </button>
</body>
</html>
deletecheck.js

function deleteApple(loc){
	<!--選んだ項目の地域の名前をパラメータにする。  -->
	<!-- 下の内容の、「確認」と「キャンセル」があるメッセージを出す。
	let check = confirm(`${loc} 地域のデータを削除しますか?`)
	if(check == true){ <!--上のメッセージで「確認」を押したなら-->
	<!--パラメータの地域(現在選択された項目の地域名)をパラメータにして、削除を担当する「AppleDeleteController」Servletに移動する。 -->
	location.href= "AppleDeleteController?deletelocation=" + encodeURI(loc);
	}
}

次は、削除する地域名を持って、実際の削除メソッドを実行し、ページに出力するデータを更新してくれる「AppleDeleteController」になる。

AppleDeleteController.java

package com.inchel.Sep141.apple;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/AppleDeleteController")
public class AppleDeleteController extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//DBのデータを削除して、データを更新した後出力する。
		AppleDB.getAppledb().deleteAppleDB(request);
		AppleDB.getAppledb().getPageCount(request);
		AppleDB.getAppledb().getAppleDB(request);
		request.setAttribute("cp", "appleoutput.jsp");
		request.getRequestDispatcher("index.jsp").forward(request, response);
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}
}

最後に、実際にDBのデータを削除する「deleteAppleDB」メソッドがある「AppleDB.java」になる。

AppleDB.java

public void deleteAppleDB(HttpServletRequest request) {

		Connection con = null;
		PreparedStatement pstmt = null;
		try {
		con = InchelDBManager.connect("inchelPool");
		//jsでのパラメータ「deletelocation」を基準にDBのデータを削除する。
		String location = request.getParameter("deletelocation");
		String sql = "delete from sep14_apple where a_location=?";
		pstmt = con.prepareStatement(sql);
		pstmt.setString(1, location);
		
		//上のSQL文がうまく作動して、項目1つが削除されたら
		if(pstmt.executeUpdate() == 1) {
			request.setAttribute("r", "削除成功");
		} else {
			request.setAttribute("r", "削除失敗");
		}
			
		} catch(Exception e) {
			
		}



以上で、WEBページでDBに接続してデータを追加(Create)、読み込み(Read)、変更(Update)、削除(Delete)する例文を全部まとめた。

WEBページ-DB連携を通じてCRUDをすることは1番基本的なWEB開発であるので、今回の例文で終わらないらしい。次はWEBページで、DBを使って会員登録(Signin)、ログイン(Login)、会員情報修正、脱退をする新しいCRUD例文をまとめる。

Discussion