さらなるサンプル

今度はMVCモデル(JavaBeansとJSPとServletの連携)というものでJDBCを扱ってみる。 一応Index/索引システムを一通り実現しているのでプログラムは短くはないが、 JDBC自体は今までで出てきたものとあまり変わらない。(プロジェクトの発表には使用してないです。参考程度に・・・。)

まず下準備

今までのではフィールドが足りないので、新たなテーブルを定義する。

CREATE TABLE t99xxxxx_tbl2(
    id serial,
    concept varchar(8),
    name varchar(64),
    url varchar(256),
    comment text,
    password varchar(10),
    time timestamp default current_timestamp
);
TIMESTAMP型は日付+時刻を表すデータ型であり、DEFAULT CURRENT_TIMESTAMPと書くと デフォルト値をレコード作成時点の時刻にするという意味になる。

このプログラムのシステム

このプログラムはServlet1つ(jdbcMvcSample.java)、JSP3つ(show.jsp、searchresult.jsp、updateform.jsp)、JavaBeans1つ(dbConnBean.java)から成っている。Servletは、クライアントからリクエストがあった時のシステムの流れを制御し、各JSPは結果などの表示を受け持ち、そしてJavaBeansは実際のDBへのアクセスなどのロジック実行を受け持つ。

Servletはクライアントからリクエストがあると、フォームからのパラメータを取得し(ある場合のみ)、そのフォームの内容に応じた処理をインスタンス化したBeansに依頼し、適当なJSPにそのインスタンス化したBeansに渡して結果や入力フォームを表示させる。各JSPではJDBCにアクセスして得た結果などをServletから渡されたBeansから得る。


jdbcMvcSample.java (制御用Servlet)


package t99xxxxx_jdbc;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class jdbcMvcSample extends HttpServlet{

    public void doGet(HttpServletRequest request,HttpServletResponse response)
        throws ServletException,IOException{

        String form_command = null;
        String form_concept = null;
        String form_name = null;
        String form_url = null;
        String form_comment = null;
        String form_password = null;
        String form_keyword = null;
        int form_id = 0;

        dbConnBean dcb = new dbConnBean();

        //フォームパラメータ取得
        form_command = request.getParameter("command");
        if(request.getParameter("concept") != null){
            form_concept = new String(
                request.getParameter("concept").getBytes("8859_1"),"SJIS");
        }
        if(request.getParameter("name")!=null){
            form_name = new String(
                request.getParameter("name").getBytes("8859_1"),"SJIS");
        }
        if(request.getParameter("url")!=null){
                   form_url = new String(
                request.getParameter("url").getBytes("8859_1"),"SJIS");
        }
        if(request.getParameter("comment")!=null){
            form_comment = new String(
                request.getParameter("comment").getBytes("8859_1"),"SJIS");
        }
        form_password = request.getParameter("password");
        if(request.getParameter("keyword")!=null){
            form_keyword = new String(
                 request.getParameter("keyword").getBytes("8859_1"),"SJIS");
        }
        if(request.getParameter("id") != null){
            form_id = Integer.parseInt(request.getParameter("id"));
        }

        //実行コマンドに応じた操作
        if(form_command != null){

            //新規レコード登録
            if(form_command.equals("insert")){
                dcb.insert(form_concept,form_name,form_url,
                              form_comment,form_password);
            }

            //レコード更新(更新フォームからの送信を受け取ったとき)
            else if(form_command.equals("update")){
                dcb.update(form_concept,form_name,form_url,
                                form_comment,form_password,form_id );
            }

            //レコード更新のためのフォームの呼び出し
            else if(form_command.equals("update_form")){
                if(dcb.passcheck(form_id, form_password)){
                    //更新対象のレコードIDをBeansに設定
                    dcb.setUpdateForm(form_id);
                    //requestにBeansを登録
                    request.setAttribute("dcb",dcb);
                    //JSPの呼び出し
                    ServletContext sc = getServletContext();
                    RequestDispatcher rd =
                        sc.getRequestDispatcher("/updateform.jsp");
                    rd.forward(request,response);
                    return;                    
                }
            }

            //レコード削除
            else if(form_command.equals("delete")){
                if(dcb.passcheck(form_id, form_password)){
                    dcb.delete(form_id);
                }
            }

            //レコード検索
            else if(form_command.equals("search")){
                //検索キーワードをBeansに設定
                dcb.setSearch(form_keyword);
                //requestにBeansを登録
                request.setAttribute("dcb",dcb);
                //JSPの呼び出し
                ServletContext sc = getServletContext();
                RequestDispatcher rd =
                    sc.getRequestDispatcher("/searchresult.jsp");
                rd.forward(request,response);
                return;
            }

        }

        //requestにBeansを登録
        request.setAttribute("dcb",dcb);
        //JSPの呼び出し
        ServletContext sc = getServletContext();
        RequestDispatcher rd = 
            sc.getRequestDispatcher("/show.jsp");
        rd.forward(request,response);
    }

    public void doPost(HttpServletRequest request,HttpServletResponse response)
        throws ServletException,IOException{
        doGet(request, response);
    }
}

show.jsp (検索フォーム+全レコード内容&更新・削除選択+新規登録フォーム表示)


<%@ page contentType="text/html; charset=Shift_JIS" %>

<!-- requestに保存したBeansを取り出す -->
<jsp:useBean id="dcb" class="t99xxxxx_jdbc.dbConnBean" scope="request" />

<html><head>
<title>JDBCによるインデックス/索引システム</title>

</head>
<body>
<h2>JDBCによるインデックス/索引システム</h2>

<!-- Beansからmessageプロパティ(getMessageメソッドの値)を取り出す。 -->
<jsp:getProperty name="dcb" property="message" />

<form action="t99xxxxx_jdbc.jdbcMvcSample" mathod=post>
<input type=hidden name=command value=search>
<input name=keyword>
<input type=submit value="検索">
</form>
<hr>
<h3>登録データ一覧</h3>
<form action="t99xxxxx_jdbc.jdbcMvcSample" method=post>
撰択した記事を
<select name=command>
<option value=update_form selected>更新</option>
<option value=delete>削除</option>
</select>
する。<br>
更新・削除キー
<input type=password name=password>
<input type=submit value="実行">
<br><br><br>

<!-- 全レコード内容のHTML表をBeansから取得 -->
<jsp:getProperty name="dcb" property="allData" />

</form>

<hr><h3>データの追加</h3>
<form action="t99xxxxx_jdbc.jdbcMvcSample" method=post>
<ul>
<input type=hidden name=command value=insert>
<li>登録したい概念
<input type=radio value="概念" name=concept>概念
<input type=radio value="メソッド" name=concept>メソッド
<input type=radio value="クラス" name=concept checked>クラス
<li>名称
<input name=name>
<li>対応URL
<input name=url>
<li>注釈内容<br>
<textarea name=comment rows=5 cols=50></textarea>
<li>更新・削除用キー
<input type=password name=password>
</ul><input type=submit value="提出">
</form>

</body></html>

searchresult.jsp (レコード検索結果&更新・削除選択の表示)


<%@ page contentType="text/html; charset=Shift_JIS" %>

<!-- requestに保存したBeansを取り出す -->
<jsp:useBean id="dcb" class="t99xxxxx_jdbc.dbConnBean" scope="request" />

<html><head>
<title>JDBCによるインデックス/索引システム</title>

</head>
<body>
<h2>JDBCによるインデックス/索引システム</h2>
<hr>

<!-- Beansからmessageプロパティ(getMessageメソッドの値)を取り出す。 -->
<jsp:getProperty name="dcb" property="message" />

<form action="t99xxxxx_jdbc.jdbcMvcSample" method=post>
撰択した記事を
<select name=command>
<option value=update_form selected>更新</option>
<option value=delete>削除</option>
</select>
する。<br>
更新・削除キー
<input type=password name=password>
<input type=submit value="実行">
<br><br><br>

<!-- 検索結果のHTML表をBeansから取得 -->
<jsp:getProperty name="dcb" property="search" />

</form>

</body></html>

updateform.jsp (更新フォーム表示、もちろんデフォルトで以前の登録内容が表示される)


<%@ page contentType="text/html; charset=Shift_JIS" %>

<!-- requestに保存したBeansを取り出す -->
<jsp:useBean id="dcb" class="t99xxxxx_jdbc.dbConnBean" scope="request" />

<html><head>
<title>JDBCによるインデックス/索引システム</title>

</head>
<body>
<h2>JDBCによるインデックス/索引システム</h2>
<hr>
<h3>更新フォーム</h3>

<!-- 更新フォームHTMLをBeansから取得 -->
<jsp:getProperty name="dcb" property="updateForm" />


</body></html>

dbConnBean.java (JavaBeans、jdbcを使ったアクセス部分とそのデータの書き出し)


package t99xxxxx_jdbc;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.DriverManager;
import java.sql.Timestamp;

public class dbConnBean{

    //JDBCドライバー
    private String jdbcDriver = "org.postgresql.Driver";
    //DBサーバへのURI
    private String jdbcUri = "jdbc:postgresql://192.168.0.36/project";
    //DBユーザ名とそのパスワード
    private String jdbcUser = "xxxxx";
    private String jdbcPass = "xxxxx";
    //自由にレコードの更新や削除をするためのマスターキー
    private String MasterKey = "xxxxx";

    private int update_id = 0;
    private String searchkeyword;
    private String message;

    //コンストラクタ
    public dbConnBean(){
        //ドライバのロード
        try{
            Class.forName(jdbcDriver);
        }catch (ClassNotFoundException cnfe){
            cnfe.printStackTrace();
        }
    }

    //JSPで受け取るメッセージ(操作完了やエラーの報告など)
    public String getMessage(){
        return message;
    }

    //レコードの追加(Servletから実行)
    public void insert(String concept, String name, String url,
                       String comment, String password){

        Connection con = null;
        Statement stmt = null;
        try{
            con = DriverManager.getConnection(jdbcUri,jdbcUser,jdbcPass);
            stmt = con.createStatement();
            String sql = "INSERT INTO t99xxxxx_tbl2" +
                         " (concept, name, url, comment, password) VALUES(" +
                         "'" + concept + "'," +
                         " '" + name + "'," +
                         " '" + url + "'," +
                         " '" + comment + "'," +
                         " '" + password + "')";
            stmt.executeUpdate(sql);
            message = "レコードが追加されました。";
            stmt.close();
            con.close();
        }catch(SQLException se){
            se.printStackTrace();
        }finally{
            try{
                if(stmt != null) stmt.close();
                if(con != null) con.close();
             }catch(SQLException se){
                 se.printStackTrace();
             }
        }
    }

    //レコードの削除(サーブレットから実行)    public void delete(int id){
        Connection con = null;
        Statement stmt = null;
        try{
            con = DriverManager.getConnection(jdbcUri,jdbcUser,jdbcPass);
            stmt = con.createStatement();
            String sql = "DELETE FROM t99xxxxx_tbl2" + 
                         " WHERE id =" + id ;
            message="レコードを削除しました。";
            stmt.executeUpdate(sql);
            stmt.close();
            con.close();
        }catch(SQLException se){
            se.printStackTrace();
        }finally{
           try{
                if(stmt != null) stmt.close();
                if(con != null) con.close();
            }catch(SQLException se){
                 se.printStackTrace();
            }
        }
    }

    //レコードの更新(サーブレットから実行)
    public void update(String concept, String name, String url,
                       String comment, String password, int id){
        Connection con = null;
        Statement stmt = null;
        try{
            con = DriverManager.getConnection(jdbcUri,jdbcUser,jdbcPass);
            stmt = con.createStatement();
            String sql = "UPDATE t99xxxxx_tbl2 SET" + 
                         " concept = '" + concept + "'," +
                         " name = '" + name + "'," +
                         " url = '" + url + "'," +
                         " comment = '" + comment + "'," +
                         " time = CURRENT_TIMESTAMP" +
                                " WHERE id =" + id +
                         " AND password ='" + password + "'";

            stmt.executeUpdate(sql);
            message = "レコードが更新されました。";
            stmt.close();
            con.close();
        }catch(SQLException se){
            se.printStackTrace();
        }finally{
            try{
                if(stmt != null) stmt.close();
                if(con != null) con.close();
            }catch(SQLException se){
                 se.printStackTrace();
            }
        }
    }

    //パスワードチェック(サーブレットから実行)
    public boolean passcheck(int id, String passwd){
        Connection con = null;
        Statement stmt = null;
        ResultSet rs = null;
        boolean passok = false;
        if(id == 0){
            message = "<font color=red>" +
                      "記事が選択されていません。</font>";
        }
        else{
              try{
                con = DriverManager.getConnection(jdbcUri,jdbcUser,jdbcPass);
                stmt = con.createStatement();
                rs = stmt.executeQuery(
                    "SELECT password FROM t99xxxxx_tbl2" +
                    " WHERE id =" + id);
                rs.next();
                String password = rs.getString("password");

                if(!password.equals(passwd) &&
                              !MasterKey.equals(passwd)){
                           message = "<font color=red>" +
                              "キーが違います。</font>";
                    rs.close();
                    stmt.close();
                    con.close();
                }
                else {
                    rs.close();
                    stmt.close();
                    con.close();
                    passok = true;
                }
            }catch(SQLException se){
                se.printStackTrace();
            }finally{
                try{
                    if(rs != null) rs.close();
                    if(stmt != null) stmt.close();
                    if(con != null) con.close();
                }catch(SQLException se){
                     se.printStackTrace();
                }
            }
        }
        return passok;
    }

    //全レコード表示(show.jspから呼び出される)
    public String getAllData(){
        Connection con = null;
        Statement stmt = null;
        ResultSet rs = null;
        String html = "<table>";
        try{
            con = DriverManager.getConnection(jdbcUri,jdbcUser,jdbcPass);
            stmt = con.createStatement();
            String ConceptName[] = {"概念" , "メソッド", "クラス"};
            for(int i = 0; i < 3 ; i++){
                html += "<tr><td colspan=2><hr><h3>" + ConceptName[i] +
                        "</td></tr>";
                String sql = "SELECT * FROM t99xxxxx_tbl2" +
                             " WHERE concept = '" + ConceptName[i] + "'" +
                             " ORDER BY concept";
                rs = stmt.executeQuery(sql);
                while(rs.next()){
                    int id = rs.getInt("id");
                    String concept = rs.getString("concept");
                    String name = rs.getString("name");
                    String url = rs.getString("url");
                    String comment = rs.getString("comment");
                    Timestamp time = rs.getTimestamp("time");
                    html += "<tr><td colspan=2><hr></td></tr>";
                    html += "<tr><td colspan=2><b>";
                    html += "<input type=radio name=id value=" + id + ">";
                    html += name + "(" + concept + ")</b></td></tr>";
                    html += "<tr><td width=50 valign=top>URL:</td>";
                    html += "<td><a href=\""+ url +"\">";
                    html += url +"</a></td></tr>";
                    html += "<tr><td valign=top>コメント:</td>";
                    html += "<td>" + comment + "</td></tr>";
                    html += "<tr><td valign=top>最終更新日:</td>";
                    html += "<td>" + time + "</td></tr>";
                }
            }
            html += "<tr><td colspan=2><hr><br><br></td></tr></table>";
            rs.close();
            stmt.close();
            con.close();
        }catch(SQLException se){
            se.printStackTrace();
        }finally{
            try{
                if(rs != null) rs.close();
                if(stmt != null) stmt.close();
                if(con != null) con.close();
            }catch(SQLException se){
                 se.printStackTrace();
            }
        }
        return html;
    }

    //Update用フォームのidを設定(サーブレットから実行)
    public void setUpdateForm(int id){
        update_id = id;
    }

    //Update用のフォームの表示(updateform.jspで呼び出される)
    public String getUpdateForm(){
        String html = "<form action=\"./t99xxxxx_jdbc.jdbcMvcSample\" method=post>";
        try{
            Connection con = DriverManager.getConnection(jdbcUri,jdbcUser,jdbcPass);
            Statement stmt = con.createStatement();
            String sql = "SELECT * FROM t99xxxxx_tbl2" + 
                         " WHERE id = " + update_id;
            ResultSet rs = stmt.executeQuery(sql);
            html += "<ul>" +"<input type=hidden name=command value=update>";
            html += "<input type=hidden name=id value=" + update_id + ">";
            html += "<li>概念";
            String conceptName[] = {"概念", "メソッド", "クラス"};
            rs.next();
            String concept = rs.getString("concept");
            String name = rs.getString("name");
            String url = rs.getString("url");
            String comment = rs.getString("comment");
            String password = rs.getString("password");
            for(int i=0; i<3; i++){
                String checked = "";
                if(concept.equals(conceptName[i])){
                    checked=" checked";
                }
                html += "<input type=radio value=\"" +
                    conceptName[i] + "\" name=concept" + checked
                    + ">" + conceptName[i];
            }
            html += "<li>名称";
            html += "<input name=name value=\"" + name + "\">";
            html += "<li>対応URL";
            html += "<input name=url value =\"" + url + "\">";
            html += "<li>注釈内容<br>";
            html += "<textarea name=comment rows=5 cols=50>";
            html += comment + "</textarea>";
            html += "</ul><input type=submit value=\"提出\">";
            html += "<input type=hidden name=password value=\"" + password + "\">";
            html += "</form>";
            rs.close();
            stmt.close();
            con.close();
        }catch(SQLException se){
            se.printStackTrace();
        }finally{
            try{
                if(rs != null) rs.close();
                if(stmt != null) stmt.close();
                if(con != null) con.close();
            }catch(SQLException se){
                 se.printStackTrace();
            }
        }
        return html;
    }

    //検索キーワードを設定(サーブレットから実行)
    public void setSearch(String key){
        searchkeyword = key;
        message = "<h3>検索結果(キーワード:\"" + key +  "\")";
    }

    //検索結果の表示(searchresult.jspで呼び出される)
    public String getSearch(){
        String html = "<table>";
        try{
            Connection con = DriverManager.getConnection(jdbcUri,jdbcUser,jdbcPass);
            Statement stmt = con.createStatement();
            //WHERE column LIKE %hoge%で、column列にhogeという
            //文字列を含むレコード、という意味。
            String sql = "SELECT * FROM t99xxxxx_tbl2" +
                         " WHERE name LIKE '%" + searchkeyword + "%'" +
                         " OR comment LIKE '%" + searchkeyword + "%'" +
                         " ORDER BY name";
            ResultSet rs = stmt.executeQuery(sql);
            while(rs.next()){
                int id = rs.getInt("id");
                String concept = rs.getString("concept");
                String name = rs.getString("name");
                String url = rs.getString("url");
                String comment = rs.getString("comment");
                Timestamp time = rs.getTimestamp("time");
                html += "<tr><td colspan=2><hr></td></tr>";
                html += "<tr><td colspan=2><b>";
                html += "<input type=radio name=id value=" + id + ">";
                html += name + "(" + concept + ")</b></td></tr>";
                html += "<tr><td width=50 valign=top>URL:</td>";
                html += "<td><a href=\""+ url +"\">";
                html += url +"</a></td></tr>";
                html += "<tr><td valign=top>コメント:</td>";
                html += "<td>" + comment + "</td></tr>";
                html += "<tr><td valign=top>最終更新日:</td>";
                html += "<td>" + time + "</td></tr>";
            }
            html += "<tr><td colspan=2><hr><br><br></td></tr></table>";
            rs.close();
            stmt.close();
            con.close();
        }catch(SQLException se){
            se.printStackTrace();
        }finally{
            try{
                if(rs != null) rs.close();
                if(stmt != null) stmt.close();
                if(con != null) con.close();
            }catch(SQLException se){
                 se.printStackTrace();
            }
        }
        return html;
    }
}



実行の流れ

全レコード表示(フォーム送信なし)

レコード登録

更新用フォーム呼び出し

レコード更新

レコード削除

レコード検索




実行結果

こんな感じです。
show.jspupdateform.jsp
searchresult.jsp



←もどる
ホームへ