Servlet/JSP 応用編05 商品の検索と登録

はじめに

今回の記事では、サーバにある商品を検索したり、商品を登録するプログラムを書きたいと思う。
方法としては、商品の全探索と変わりはあまりない。select文を使いましょう。あとは、where句で条件を足すだけで詳細に検索をすることができる。しかし、このままでは、完璧に商品名を打たないと検索結果にでてこなくなる。これでは、非常に使いにくい検索になってしまう。そこで、like演算子ワイルドカードを用いる。使い方は、
where 列名 like '%キーワード%'
で良い。「%」はワイルドカードの一つで、0文字以上の任意の文字列を表す。つまり、「%キーワード%」といった使い方をすれば、「キーワード」という言葉に前後何か言葉があっても結果としてでてくるのだ。今回はこれを利用したプログラムを書いていく。

検索プログラムの作成

中身の処理を書く前に、検索をしやすいように専用の欄を作成する。プログラムは以下の通りになる。

<%@page contentType="text/html; charset=UTF-8" %>
<%@include file="../header.html" %>

<p>検索キーワードを入力してください</p>
<form action="search" method="post">
<input type="text" name="keyword">
<input type="submit" value="検索">
</form>

<%@include file="../footer.html" %>

ここで最も重要なのは、テキストボックスである。このボックスに入力されたテキストがjavaファイルに処理を送るためである。なので、name属性には、分かりやすく、「keyword」と名前を付けましょう。
次は、実際に処理をするためのサーブレットの作成をする。先にプログラムを貼っておく。

public class Search extends HttpServlet{

    public void doPost(HttpServletRequest request , HttpServletResponse response)
     throws ServletException , IOException{
        PrintWriter out = response.getWriter();
        Page.header(out);
        out.print("aaaaa");
        try{
            InitialContext icnew InitialContext();
            DataSource ds = (DataSource)ic.lookup("java:/comp/env/jdbc/book");
            Connection con = ds.getConnection();

            String keyword = request.getParameter("keyword");

            PreparedStatement st = con.prepareStatement
            ("select * from product where name like ?");
            st.setString(1,"%"+keyword+"%");
            ResultSet rs = st.executeQuery();
            out.print("ccc");

            while(rs.next()){
                out.println(rs.getInt("id"));
                out.print(":");
                out.println(rs.getString("name"));
                out.print(":");
                out.println(rs.getInt("price"));
                out.println("<br>");
            }

            st.close();
            con.close();
        }catch(Exception e){
            out.print("bbb");
            e.printStackTrace(out);
        }
        Page.footer(out);
    }
}

データベース接続までは前回の記事と全く同じなので、解説を省略する。

最初に大事なのは、keyword変数にgetParameterメソッドで、「keyword」の要素をとり、格納している。つまり、この変数に、検索内容を格納しているということである。

次に、その検索ワードにはじめに記した、like演算子ワイルドカードを加え、データベースから検索しなければならない。

なので、prepareStatementでSQL文を書いている。「?」マークがあるが、これはプレースホルダを利用している。「?」マークの場所はあとから値を入れることができる。そして、値を入れるためには、setStringメソッド、setIntメソッドを使う。引数は二つあり、一つ目には、何個目の「?」に値を入れるのかを指定する。今回の場合は一つしかないので、「1」と書く。次に、二つ目の引数には、入れたい値を書く。今回はキーワードの中身を入れる。

では、実際にブラウザで結果を見てみましょう。

f:id:kouki-matsuura:20201009153741p:plain

「軍艦」というキーワードを指定する。ワイルドカードを使わない検索だと、「軍艦」という商品がない限りはヒットすることはない。

結果を見てみる。

f:id:kouki-matsuura:20201009153744p:plain

ワイルドカードを使用しているため、「〇〇軍艦」という結果もでてきた。これで、like演算子がどのようなものか分かっていただけたかと思う。

登録プログラムの作成

次は、商品をデータベースに登録するプログラムを作成したいと思う。このプログラムで知ってほしいのは、「executeUpdate」メソッドである。
追加、更新、削除の場合は検索と違い、Resultsetを利用した処理を記述するわけではないので、処理が成功したかどうかを知ることができない。そこで、代わりに使用するのが、executeUpdateメソッドである。このメソッドの返り値は、SQL文によって、変更された行数であるため、0行が返ってきたときには、処理は失敗しているということが分かる。
では、実際に使っていく。まずは、JSPファイルの作成をする。

<%@page contentType="text/html; charset=UTF-8" %>
<%@include file="../header.html" %>

<p>追加する商品を入力してください</p>
<form action="insert" method="post">
商品名<input type="text" name="name">
価格<input type="text" name="price">
<input type="submit" value="追加">
</form>

<%@include file="../footer.html" %>

大事なのは、商品名のテキストボックスと、価格のテキストボックスであり、ここで入力されたものでSQL文を作成し、データベースに追加をする。そのような処理を行う。サーブレットを下記に載せる。

public class Insert extends HttpServlet{

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

        PrintWriter out = response.getWriter();
        Page.header(out);
        try{
            InitialContext ic = new InitialContext();
            DataSource ds = (DataSourceic.lookup
            ("java:/comp/env/jdbc/book");
            Connection con = ds.getConnection();

            String name = request.getParameter("name");
            int price = Integer.parseInt(request.getParameter("price"));

            PreparedStatement st = con.prepareStatement
            ("insert into product values(null , ? , ? )");
            st.setString(1name);
            st.setInt(2price);
            int line = st.executeUpdate();

            if(line > 0){
                out.println("追加に成功しました");
            }else{
                out.println("追加に失敗しました");
            }

            st.close();
            con.close();
        }catch(Exception e){
            e.printStackTrace(out);
        }

        Page.footer(out);
    }
}

検索プログラムと同じように、getParameterメソッドで入力内容を変数に格納する。prepareStatementメソッドでは、プレースホルダを二つ使う。入力内容が二つあるためである。今回の場合は、一つ目は、商品名であるからsetStringメソッドを、二つ目は、価格であるからsetIntメソッドを使う。プレースホルダに、入力が完了すれば、そのSQLをデータベースに送る。変更が起きれば、変数lineに変更が起きた行数が返り値として代入される。それが0より大きければ、「追加に成功した」と画面に出すことにする。では、実行する。

 

f:id:kouki-matsuura:20201009160824p:plain

商品名は「鮭」、価格は「1000」で入力する。追加ボタンを押すと、コマンドプロンプトに成功のメッセージが届いた。

f:id:kouki-matsuura:20201009160838p:plain

そして、結果を見るために、全探索をすると、

 

f:id:kouki-matsuura:20201009160831p:plain

今までの商品にプラスして、鮭がたされていることが分かる。

以上で、検索と追加のプログラムを解説した。