SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

GlassFishからアプローチするJava

GlassFishからアプローチするJava~入門編~
第6回「Webアプリケーションの作成 ON DELETE CASCADE」

買い物かごへの削除、更新機能の実装

ダウンロード サンプルコード (16.5 KB)

買い物かごを再表示するためのRefreshBasketServletクラスを作成

 Servletの作成の仕方は既に説明しているため割愛します。作成の仕方が分からない方は当連載第2回目の3ページ以降で説明しています。

 買い物かごのへの削除・追加のためのServletを作成します。まずは本数を増減させた場合に金額が正確に表示されるよう実装します。図2のように内容は第5回で作成したBasketServletクラスをほぼ同じです。

図2.RefreshBasketServletクラスのprocessRequestメソッド
001:    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
002:    throws ServletException, IOException {
003:
004:        ArrayList basketItems = new ArrayList();
005:
006:        String[] basketItemIds = request.getParameterValues("id");
007:        String[] allQuantity = request.getParameterValues("quantity");
008:
009:        int basketId = 0;
010:
011:        BasketHelper basketHelper = new BasketHelper();
012:        // ログインしたユーザidをもとにデータベースからbasket情報を
013:        // 取得する。第5回は固定で「tomoharu」とする
014:        basketId = basketHelper.getBasketId("tomoharu");
015:
016:        basketHelper.updateBasketItems(basketItemIds, allQuantity);
017:
018:        basketItems = basketHelper.getBasketItems(basketId);
019:        request.getSession().setAttribute("basket", basketItems);
020:
021:        // ImoshochuShop.jspに遷移する
022:        RequestDispatcher rd = request.getRequestDispatcher("/ImoshochuShop.jsp");
023:        rd.forward(request, response);
024:
025:    } 

 BasketServletクラスと違うところは、JSPから受け取るパラメタの違い(6、7行目)と銘柄の挿入ではなく更新を行っている箇所(16行目)です。ただし、本数が0本の銘柄を削除することが仕様であるため、厳密にはupdateBasketItemsという名称ですが、削除処理も行っています。BasketHelperクラスのupdateBasketItemsはそのままDAOクラスのupdateItemsメソッドを呼び出しているだけであるため割愛します。サンプルコードでご確認ください。

BasketDAOImplクラスの変更

 まずは図3のように定数として定義しているSQLに追加、変更します。

図3.SQLの追加・変更
001:    private static final String SQL_INSERT_BASKET
		= "insert into basket values(0, ?)";
002:    private static final String SQL_GET_BASKETID
		= "select * from basket where user_id = ?";
003:    private static final String SQL_INSERT_BASKET_ITEM
		= "insert into basket_item values(0, ?, ?, 1)";
004:    private static final String SQL_UPDATE_BASKET_ITEM
		= "update basket_item set quantity = ? where id = ?"; // 第6回で追加
005:    private static final String SQL_DELETE_BASKET_ITEM
		= "delete from basket_item where id = ?"; // 第6回で追加
006:    // 第6回でbasket_itemのidを返すよう変更
007:    private static final String SQL_GET_ALL_BASKET_ITEMS
		= "select b.id as basket_item_id, m.id, m.name, m.price, b.meigara_id, b.quantity"
008:            + " from (basket_item as b inner join meigara as m on b.meigara_id = m.id)"
009:            + " where basket_id = ?";

 4行目と5行目が追加したSQL文です。7行目がbasket_itemのidを取得するよう変更しています。説明が遅れましたが、SQL文の中にある「?」がプレースフォルダと呼ばれるもので、後で値を設定できるように用意されたものです。プレースフォルダを使用する場合はStatementではなくPreparedStatementを使用します。具体的にはupdateItemsメソッドで説明します。

 次にupdateItemsメソッドを追加します。図4がupdateItemsメソッドの抜粋です。

図4.BasketDAOImplクラスのupdateItemsメソッド(抜粋)
001:        Connection conn = null;
002:        PreparedStatement updatePreparedStatement = null;
003:        PreparedStatement deletePreparedStatement = null;
004:        ArrayList updatedBasketItemIds = new ArrayList(Arrays.asList(basketItemIds));
005:        ArrayList updatedAllQuantity = new ArrayList(Arrays.asList(allQuantity));
006:        try {
007:            conn = getConnection();
008:            updatePreparedStatement = conn.prepareStatement(SQL_UPDATE_BASKET_ITEM);
009:            deletePreparedStatement = conn.prepareStatement(SQL_DELETE_BASKET_ITEM);
010:            for (int i = 0; i < updatedBasketItemIds.size(); i++) {
011:                int basketItemId = Integer.parseInt(updatedBasketItemIds.get(i));
012:                int quantity = Integer.parseInt(updatedAllQuantity.get(i));
013:                if (quantity == 0) {
014:                    deletePreparedStatement.setInt(1, basketItemId);
015:                    deletePreparedStatement.executeUpdate();
016:                } else {
017:                    updatePreparedStatement.setInt(1, quantity);
018:                    updatePreparedStatement.setInt(2, basketItemId);
019:
020:                    updatePreparedStatement.executeUpdate();
021:                }
022:
023:            }
024:        } catch(SQLException se) {

 少しトリッキーなコーディングになっていますが、可読性を高めるということでご勘弁ください。3、4行目で2つのPreparedStatementを定義しています。3行目が更新用、4行目が削除用となっています。

 このように2つ定義したのは本数(quantity)が0の場合、削除。0以外の場合、更新する必要があるためです。13行目から21行目が削除と更新処理のコードです。13行目で先述のSQL_DELETE_BASKET_ITEMの?に画面から取得したbasket_itemのidを設定しています。このようにプレースフォルダは異なった値を入れるためのもので、プログラミング言語の変数に相当します。ただし、SQLに出現する?の順番に従って1から番号を指定する必要があります。

 14行目で不完全であったSQL文が実行できるようになりました。15行目でSQL文を実行しています。これで本数が0の銘柄は買い物かごから削除されます。17、18、20行目が更新の場合の処理です。一点だけ注意しないといけないのは、データベースに接続し、処理を行い、終了したらリソースを解放するような処理は、ほとんどの場合一から作ることはなく、別のプロジェクトのプログラムからコピーして作成するが故にリソースの解放を忘れてしまいがちになることです。この例で言うと、PreparedStatementを2つ生成しているので、2つともfinallyブロックでcloseメソッドを使ってリソースを解放しなくてはなりません。

 ここまでで、冒頭で説明した仕様の2と3を実装したことになります。

次のページ
合計、送料、総合計の計算

この記事は参考になりましたか?

GlassFishからアプローチするJava連載記事一覧

もっと読む

この記事の著者

川久保 智晴(カワクボ トモハル)

haruプログラミング教室(https://haru-idea.jp/)主宰。COBOL、FORTRANで13年、Javaを中心としたWeb開発で11年。3つしか言語知らないのかというとそうでもなく、sed/awk、Perl、Python, PHP,  C#, JavaScriptなども一時期は業...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4920 2010/03/10 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー