😊

Servlet、JSP、Java、MVCパタンにJDBCを適応したDB連携~CRUDのR(Read)例文

2023/09/20に公開

前書き

今回は、今までのWEBを作る言語全部(Servlet, JSP, JS, Java)とMVCパタンを使って、OracleDBからデータを読み込む例文を作成してみた。

今までしてきたWEBページ作りのコードは今回も簡単にまとめて、ORACLEDBに直接要請するSQL言語文と、その結果を扱うためのJAVA文法を中心にまとめてみる。

今回の例文はCRUDのR(Read)に当たるコードで、DBに要請してDBのデータを持ってくる同時に、持ってきたデータを何個づつ分けて、ページに分けて出力することまでしてみる予定である。

例文の前に、実行してからの流れのまとめ

今回の例文はコードの量が多くて、コードを見る前にコードの流れを先にまとめる。

この流れでコードが問題なしに行けたら、下記のようにページ数と、選んだページによるデータが出力される。

では、上記したコードをまとめてみよう。

例文

最初は、プログラムを実行する「HomeController.java」Servletになる。

HomeController
package com.inchel.Sep141.main;

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("/HomeController")
public class HomeController extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	// 最初に実行すると、home.jsp住所を持って「index.jsp」に移動する。
		if(!request.getParameterNames().hasMoreElements()) {
			request.setAttribute("cp", "home.jsp"); 
		}
		request.getRequestDispatcher("index.jsp").forward(request, response);
	}

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

}

次は、プログラムを実行した後、「index.jsp」の中でincludeされるページ、「home.jsp」になる。特別な内容はない。

home.jsp

<%@ 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>

	ここは1番最初に実行される「home.jsp」です。<p>
	テスト
	<p>テスト<p>テスト<p>テスト<p>テスト<p>テスト<p>テスト<p>

</body>
</html>
	

次は、全てのページをincludeして出力する、メインページになる「index.jsp」である。ここの中にはincludeして出力ページと、他のメニューに移動するボタンなどのコードがある。

index.jsp
<%@ 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>

<!-- <link rel = "stylesheet" href="css/style.css"> -->

<script type = "text/javascript" src = "js/ValidCheck.js"></script>

</head>
<body>

	<header><h2> 題目 </h2></header>
	
	<main>
	<div>
	<jsp:include page = "${cp}" /><!--各ページに移動すると、「index.jsp」のなかでここでページを出力する。 -->
	</div>
	</main>
	
	<nav>
	<div> <a href = "AppleDBController"> AppleDB </a> </div>
	<div> <a href = "A"> Banana</a> </div>
	<div> <a href = "B"> Coconut</a> </div>
	<div> <a href = "DBCController"> DB連結確認</a> </div>
	</nav>
	
</body>
</html>

次は、「AppleDB」を押したときに実行される「AppleDBController.java」Servletになる。

AppleDBController.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;

/**
 * Servlet implementation class AppleDBController
 */
@WebServlet("/AppleDBController")
public class AppleDBController extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		AppleDB.getAppledb().getPageCount(request); //ページ数を計算するメソッド
		AppleDB.getAppledb().getAppleDB(request); //ページに当たるデータをDBから受けて、HTMLで出力するためにSetAttributeするメソッド
		
		request.setAttribute("cp", "appleoutput.jsp"); //上の処理が終わったら、「index.jsp」でincludeするために住所をSetAttributeする。
		request.getRequestDispatcher("index.jsp").forward(request, response); // 「index.jsp」に移動する。
	}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}
}

次は、実際にページ数を計算して、DBに接続するなどの機能を担当するメソッドがある、「AppleDB.java」になる。今回の例文に使えるメソッド以外のコードもあるが、ここでは省略する。今回の例文では「getPageCount」、「getAppleDB」メソッドだけ書く。

AppleDB.java

package com.inchel.Sep141.apple;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;

import javax.servlet.http.HttpServletRequest;

import com.inchel.db.manager.InchelDBManager;

public class AppleDB {
	
	private static final AppleDB APPLEDB = new AppleDB();
	private AppleDB() {
		// TODO Auto-generated constructor stub
	}
	public static AppleDB getAppledb() {
		return APPLEDB;
	}
	
	private int pageNumber = 1;
	private int dataCount = 0;

	public void getPageCount(HttpServletRequest request) {
		
	Connection con = null; //DBに接続するためのインスタンス
	PreparedStatement pstmt = null; //DBに接続するためのインスタンス
	ResultSet rs = null; //DBに接続するためのインスタンス
	dataCount = 0; //DBにあるデータの数を受ける変数
	
	int pageCount = 1; //基本的に、1ページを出力するために1に初期化
	
	try {
	con = InchelDBManager.connect("inchelPool"); //DBに接続する。
	String sql = "SELECT * FROM sep14_apple ORDER BY a_price"; //DBに要請するSQL文を作成。
	//「sep14_apple」テーブルにあるすべてのデータを、「a_price」値を基準に整列して持ってきてください」という意味。
	pstmt = con.prepareStatement(sql);//SQL文をDBに要請するために必要なコード
	rs = pstmt.executeQuery();//SQL文を実際に送って、結果を受ける。
		
	while(rs.next()) { //受けたデータがないまで、1づつデータの数を数える。
		dataCount++;
	}
			
	pageCount = dataCount % 5 == 0 ? dataCount / 5 : (dataCount / 5) + 1; //データの数を数えた後、データを5個づつ分けて1つのページにするための変数
	//System.out.println("pageCount : " + pageCount);
	request.setAttribute("pagecount", pageCount);//計算したページ数をSetAttributeする。
	} catch(Exception e) {
		
	}
	InchelDBManager.close(con, pstmt, rs); //DBを使い終えたら、closeする。
}
	
	//ページ数に当たるデータをDBに要請して、結果を受けるメソッド
	public void getAppleDB(HttpServletRequest request) {
		
	Connection con = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;
		
	//ページ数のボタンを押したら押したページ番号をpageNumber変数にいれ、違うと1と代入
	try{
	if(request.getParameter("pagenumber") != null) {
		pageNumber = Integer.parseInt(request.getParameter("pagenumber"));
	} else {
		pageNumber = 1;
	}
			
	//DBに接続
	con = InchelDBManager.connect("inchelPool");
	
	//下のSQL文の内容をまとめると下記のようになる。
	//1) a_priceを基準に整列
	//2) 整列したデータに、1から最後まで「A_PAGENUM」を付ける。
	//3) 「A_PAGENUM」を、ページ数に当たる範囲(1PAGEであると1~5番データを、2PAGEであると6~10番データを受ける)にして、そのデータを受ける。
	
	String sql = "SELECT a_location, a_color, a_taste, a_price, a_introduce, \"A_PAGENUM\" "
	+ "FROM(SELECT a_location, a_color, a_taste, a_price, a_introduce, "
	+ "dense_rank() over(order by a_price) \"A_PAGENUM\" FROM sep14_apple) "
	+ "WHERE \"A_PAGENUM\" BETWEEN " + ((pageNumber-1)*5 + 1) + " AND " + pageNumber*5;
			
	pstmt = con.prepareStatement(sql); //DBに要請するためのコード
	rs = pstmt.executeQuery(); //DBに実際に要請する。
	
	//受けた結果をWEBページに送るために、ArrayListを使用
	ArrayList<AppleDTO> aList = new ArrayList<AppleDTO>();
	AppleDTO a = null;
	
	//DBから受けたデータを、上のArrayListに入れる。
	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"));
		aList.add(a);
	}
	
	//DBから受けたデータを入れたArrayListをWEBページで使うためにSetAttributeする。
	request.setAttribute("alist", aList);
			
	} catch(Exception e){
		e.printStackTrace();
	}
		
	try {
	InchelDBManager.close(con, pstmt, rs); //DBを使い終えたらcloseする。
	} catch(Exception e) {
			
	}
}
		
}
	
}


最後に、DBから受けたデータを出力するWEBページ、「appleoutput.jsp」になる。

appleoutput.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>
</head>
<body>

	<hr>
	ここはAppleDBです <br>
	
	<!--javaコードで、SetAttributeしたArrayListを受けてそのフィールドを出力 -->
	<%
		ArrayList<AppleDTO> aList = (ArrayList<AppleDTO>)request.getAttribute("alist");
		for(int i = 0; i < aList.size(); i++){
	%>
		<div> <a href = "AppleInfoController?getinfolocation=<%=aList.get(i).getLocation()%>"> 
		地域 : <%=aList.get(i).getLocation() %> 値段 : <%=aList.get(i).getPrice() %>
		</a>
		</div>
		 <p><p>
	<% 	
		}
	%>
	<hr>
	<!--数えておいたページ数をここで出力。 -->
	<!--他のjspであるが、コードが少なくて下に注釈でコードを書いておく。-->
	<jsp:include page = "pages.jsp" />
		
	<!--
        「getPageCount」メソッドで数えたページ数を利用して、for文を使って番号を作る。
	<c:forEach var="v" begin="1" end="${pagecount}" step="1">
        <a href = "AppleDBController?pagenumber=${v}"> ${v}</a>
	</c:forEach>
	-->
	
</body>
</html>

以上で、WEBページでDBに接続して、データを要請して出力するR(Read)例文をまとめてみた。

次はCRUDのC(Create)、つまりWEBページで入力したデータをDBに追加する例文をまとめる。

Discussion