Servlet、JSP、Java、MVCパタンにJDBCを適応したDB連携~CRUDのR(Read)例文
前書き
今回は、今までのWEBを作る言語全部(Servlet, JSP, JS, Java)とMVCパタンを使って、OracleDBからデータを読み込む例文を作成してみた。
今までしてきたWEBページ作りのコードは今回も簡単にまとめて、ORACLEDBに直接要請するSQL言語文と、その結果を扱うためのJAVA文法を中心にまとめてみる。
今回の例文はCRUDのR(Read)に当たるコードで、DBに要請してDBのデータを持ってくる同時に、持ってきたデータを何個づつ分けて、ページに分けて出力することまでしてみる予定である。
例文の前に、実行してからの流れのまとめ
今回の例文はコードの量が多くて、コードを見る前にコードの流れを先にまとめる。
この流れでコードが問題なしに行けたら、下記のようにページ数と、選んだページによるデータが出力される。
では、上記したコードをまとめてみよう。
例文
最初は、プログラムを実行する「HomeController.java」Servletになる。
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」になる。特別な内容はない。
<%@ 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して出力ページと、他のメニューに移動するボタンなどのコードがある。
<%@ 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になる。
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」メソッドだけ書く。
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」になる。
<%@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