🗄️
[DB]DAOパターンでの実装
◆はじめに
前回がまだの方は、こちらからお読みください。
DBAccessorに、SQL文を記述してデータベースに命令を送信する方法をご紹介ました。
今回は、「DAOパターン」(通称:DAO)を利用して、
画面の挙動としては同じですが、より便利に
データベースに命令を送信する方法をご紹介します。
「select」「insert」「update」「delete」ボタンがあり、
データベースにデータを送信したり、呼び出したりできます。
「select」ボタンを押すと、データベースに登録されていた文字が表示されます。
今回は、「select」のみDAOで動作する実装になっています。
◆DAOパターンとは
「Data Access Object パターン」の略です。通称DAOです。
DAOは、DAOクラスを作成してオブジェクトやリストの形でデータベースに送ったものを、
途中でSQLの命令文に勝手に変換してくれます。
データベースのアクセスにDAOを利用することで、
例えば、DAOによういしてあるselectのメソッドを呼び出せば良いので、
汎用性があり、保守性が高くなるというメリットがあります。
実装するにあたっては、
①データベースのテーブルのレコードに対応したテーブルクラス
② ①のテーブルクラスに対するDAOのクラス
③ テーブルクラスとDAOのクラスを使用してデータベースにアクセスするコード
が必要です。
◆前提/環境など
本記事は、以下の記事の「InputFunction」プロジェクトをベースに作成します。
また、データベースは、HSQLDBを扱います。
Echo機能のServletの処理時間を計測するFilterを実装しています。
また、Sessionで結果を保持するようになっています。
過去の記事の内容を踏まえた前提で、記事は書いていますのでご了承ください。
仕様は以下です。
<Echo機能> ・文字列を入力し、送信ボタンを押すと、送信した文字列が画面に表示される。
<Validation機能> ・送信された文字列が空欄の場合は,「この項目は必須入力です。」と文字列が表示される。
<TimeFiletr機能(Listener)> ・Servletの処理時間を計測し、コンソールに表示
<Session機能> ・処理結果をSessionがリセットされるまで保持する
※本記事では、 eclipseは以下のバージョンでの画像を使用しています。
日本語化はしていません。
他のversionでの動作は確認しておりません。
◆手順
それでは、実装していきます。
今回は、「select」のみDAOで動作する実装になっています。
最後に動作確認をしたら終了です。
①ディレクトリとファイルの作成
最終的なディレクトリは、下記のようになります。
・「dao」というパッケージを作成し、
・daoのフォルダの中に、「Textdata.java」と「TextdataDao.java」を作成
②ソースコード
・Textdata.javaのソースコード
package dao;
public class Textdata{
private String text;
public void setText(String text) {
this.text = text;
}
public String getText() {
return text;
}
@Override
public String toString() {
return "Textdata [ text = " + text + " ] ";
}
}
・DAOのソースコード
textdataDao.java
package dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class TextdataDao {
static {
String driver = "org.hsqldb.jdbcDriver";
try {
Class.forName(driver);
} catch(ClassNotFoundException e){
throw new RuntimeException(e);
}
}
private static Connection getConnection() throws SQLException{
String url = "jdbc:hsqldb:hsql://localhost/mydb/textdb";
String user = "SA";
String password = "";
Connection connection = DriverManager.getConnection(url , user , password);
connection.setAutoCommit(false);
return connection;
}
public List<Textdata> selectAll(HttpServletRequest request) throws SQLException{
Connection connection = getConnection();
String sql = "SELECT * FROM textdata";
PreparedStatement statement = connection.prepareStatement(sql);
List<Textdata> ret = new ArrayList<Textdata>();
HttpSession session = request.getSession();
ArrayList<String> textlist = new ArrayList<String>();
int count = 0;
ResultSet rs = statement.executeQuery();
while (rs.next()) {
Textdata textdata = new Textdata();
String Text =rs.getString("text");
textdata.setText(Text);
System.out.println(Text);
textlist.add(Text);
count ++ ;
}
session.setAttribute("SQLmessage","読込成功");
session.setAttribute("Resultmessage",textlist);
if(count == 0) {
session.setAttribute("Resultmessage","登録されているテキストデータはありません");
}
rs.close();
statement.close();
connection.close();
return ret;
}
public int insert (Textdata textdata) throws SQLException {
Connection connection = getConnection();
String getIdsql = " SELECT NEXT VALUES FOR my_seq "
+ " FROM information_schema.system_tables "
+ " WHERE table_name = 'SYSTEM_TABLES' " ;
PreparedStatement statement = connection.prepareStatement(getIdsql);
ResultSet rs = statement.executeQuery();
rs.next();
//int id = rs.get)nt(1);
rs.close();
statement.close();
//textdata.setId(id);
String sql = " INSERT INTO textdata (text) VALUES (?) ";
statement = connection.prepareStatement(sql);
//statement.setInt(1, id);
//statement.setInt(2, textdata.getText());
//statement.setInt(1, id);
int updateCount = statement.executeUpdate();
statement.close();
connection.commit();
connection.close();
return updateCount;
}
}
・DBAccessor.javaのソースコード
DBAccessor.java
package dbaccessor;
import dao.Textdata;
import dao.TextdataDao;
import java.util.List;
import java.util.ArrayList;
import java.io.IOException;
import javax.security.auth.message.callback.PrivateKeyCallback.Request;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;
//対応するjspのFormのaction名
@WebServlet(urlPatterns = {"/dbaccess"})
//Validation機能を持たせたEchoサーブレットクラス
public class DBAccessor extends HttpServlet{
private static final long serialVersionUID = 1L;
private static final String driver = "org.hsqldb.jdbcDriver";
private static final String url = "jdbc:hsqldb:hsql://localhost/mydb/textdb";
private static final String user = "SA";
private static final String password = "";
//画面からPostされた場合に起動するメインとなるメソッド
@Override
protected void doPost(HttpServletRequest request , HttpServletResponse response)throws ServletException,
IOException {
String name = request.getParameter("SubmitType");
switch(name) {
case "select":
TextdataDao textdataDao = new TextdataDao();
List<Textdata> alltextdata;
try {
alltextdata = textdataDao.selectAll(request);
printData(alltextdata);
Textdata textdata = new Textdata();
textdata.setText("テキストデータDao");
alltextdata = textdataDao.selectAll(request);
printData(alltextdata);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case "insert":
try {
Class.forName(driver);
Connection connection = DriverManager.getConnection(url,user,password);
connection.setAutoCommit(false);
insert(connection,request);
connection.commit();
connection.close();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case "update":
try {
Class.forName(driver);
Connection connection = DriverManager.getConnection(url,user,password);
connection.setAutoCommit(false);
update(connection,request);
connection.commit();
connection.close();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
case "delete":
try {
Class.forName(driver);
Connection connection = DriverManager.getConnection(url,user,password);
connection.setAutoCommit(false);
delete(connection,request);
connection.commit();
connection.close();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
default:
//それ以外の処理
System.out.println("error");
break;
}
//リダイレクト
//コンテキストルート(InputFunction)の取得
String contextPath = getServletContext().getContextPath();
//リダイレクトpathを設定(表示させるページ→echo.jsp)
String path = contextPath + "/echo.jsp";
//実際にリダイレクトを行っている関数
response.sendRedirect(path);
}
private void printData(List<Textdata> alltextdata) {
for (Textdata textdata : alltextdata) {
System.out.println(textdata);
}
System.out.println();
}
//Insert
protected void insert(Connection connection,HttpServletRequest request) throws SQLException {
Statement statement = connection.createStatement();
HttpSession session = request.getSession();
try{
String inserttext = session.getAttribute("message").toString();
String sql = "INSERT INTO textdata (text) VALUES('" +inserttext + "')";
int updateCount = statement.executeUpdate(sql);
if (updateCount == 1) {
session.setAttribute("SQLmessage","登録成功");
System.out.println("登録成功");
} else {
session.setAttribute("SQLmessage","登録失敗");
System.out.println("登録失敗");
}
} catch (RuntimeException e) {
session.setAttribute("SQLmessage","登録失敗");
System.out.println("登録失敗");
statement.close();
return;
}
statement.close();
}
//Update
protected void update(Connection connection,HttpServletRequest request) throws SQLException {
Statement statement = connection.createStatement();
HttpSession session = request.getSession();
try {
String updatetext = session.getAttribute("message").toString();
String sql = "UPDATE textdata SET text = 'Updateテキストデータ' WHERE text = '"+updatetext+"'";
int updateCount = statement.executeUpdate(sql);
if (updateCount == 1) {
session.setAttribute("SQLmessage","更新成功");
System.out.println("更新成功");
} else {
session.setAttribute("SQLmessage","更新失敗");
System.out.println("更新失敗");
}
} catch (RuntimeException e) {
session.setAttribute("SQLmessage","更新失敗");
System.out.println("更新失敗");
statement.close();
return;
}
statement.close();
}
protected void delete(Connection connection , HttpServletRequest request) throws SQLException {
Statement statement = connection.createStatement();
String sql = "DELETE FROM textdata ";
HttpSession session = request.getSession();
int updateCount = statement.executeUpdate(sql);
if (updateCount >= 1) {
session.setAttribute("SQLmessage","削除成功");
System.out.println("削除成功");
} else {
session.setAttribute("SQLmessage","削除失敗");
System.out.println("削除失敗");
}
statement.close();
}
}
・jspのソースコード
echo.jsp
<%@page language="java" contentType = "text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@page isELIgnored= "false" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<title>Echo機能+Validation機能+TimeFilter機能(Listener)+Session機能+リロード対策+DB機能(DAO)</title>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h3>Echo機能+Validation機能+TimeFilter機能(Listener)+Session機能+リロード対策+DB機能(DAO)</h3>
<%-- リセットのリクエストパラメータを渡す--%>
<a href="echo?reset">セッションのリセット</a>
<%-- 入力フォーム --%>
<form action="echo" method="post">
<br />入力してください :
<%-- テキストボックス(m) --%>
<input type="text" name="m" />
<%-- Validationメッセージの出力 --%>
<%-- var="vm" → c:out で valueにセットする際に使う名称 --%>
<%-- [' ']には、 MessageForm.javaのテキストボックスのメッセージ保持用のパラメータ名を入れる --%>
<c:forEach items="${validationMessage['textMessage']}" var="vm">
<c:out value="${vm}"/>
</c:forEach>
<br />
<%-- 送信ボタン --%>
<input type="submit" /> <br />
</form>
<br />
<%-- Echoメッセージの出力--%>
DB送信文字列 :
<c:if test="${ not empty message }">
「${ message }」です。
</c:if>
<br />
<%-- DBAccessフォーム --%>
<form action="dbaccess" method="post" name="DataBase" onsubmit="return SQL()" >
<%-- Selectボタン --%>
<input type="submit" value="Select" onclick="DataBase.SubmitType.value='select'" />
<%-- Insertボタン --%>
<input type="submit" value="Insert" onclick="DataBase.SubmitType.value='insert'" />
<%-- Updateボタン --%>
<input type="submit" value="Update" onclick="DataBase.SubmitType.value='update'" />
<%-- Deleteボタン --%>
<input type="submit" value="Delete" onclick="DataBase.SubmitType.value='delete'" />
<c:if test="${ not empty SQLmessage }">
「${ SQLmessage }」
</c:if>
<input name="SubmitType" type="hidden" value="" />
</form>
<br />
<%-- SQL結果の出力--%>
<c:if test="${ not empty Resultmessage }">
${ Resultmessage }
</c:if>
<%-- SQL結果の出力--%>
<script type="text/javascript">
function SQL() {
if (DataBase.SubmitType.value == 'select') {
}
if (DataBase.SubmitType.value == 'insert') {
}
if (DataBase.SubmitType.value == 'update') {
}
if (DataBase.SubmitType.value == 'delete') {
}
return true;
}
</script>
</body>
DB機能に関係するコードは以上です。
それ以外のファイルのコードなどは、
別の記事をご覧ください。
③動作確認
実装ができたら
・Tomcatを起動
・以下のURLにアクセス
以下の画面が表示されます
今回は、「select」のみDAOで動作する実装になっていますので、
それでは、select文の動作を確認していきましょう。
まず、
・テキストボックスに「テキストデータ」と入力
・「insert」ボタンを押す
・「select」ボタンを押してデータを表示
下記のように表示されたら、OKです。
その他の、insert,updateやdeleteに関しては、
前回と同じ、DAOを使用していない状態での実装です。
そちらのDAOでの実装は、また機会があればご紹介したいと思います。
◆さいごに
以上です。いかがだったでしょうか。
以下のまとめ記事もどうぞご覧ください。
最後まで、ご覧いただきありがとうございました。
◆参考
本記事は、以下の書籍を大いに参考にしています。
より詳しく知りたい方は、どうぞ。
Discussion