連載
» 2009年06月24日 00時00分 公開

App EngineをjQueryでAjax化しBigtableをCRUD操作Google App Engineで手軽に試すJavaクラウド(3)(4/4 ページ)

[清野克行,有限会社サイバースペース]
前のページへ 1|2|3|4       

CRUD処理を行うサーブレット

 サーブレットでは、GETメソッドで参照処理のリクエストを受け取り、POSTメソッドで登録・更新・削除処理のリクエストを受け取って処理しています。

package erp.emp;
 
import java.io.IOException;
 
import javax.jdo.PersistenceManager;
import javax.servlet.http.*;
import java.util.Date;
import java.util.List;
import javax.jdo.Query;
import erp.emp.PMF;
import erp.emp.empmas;
 
@SuppressWarnings("serial")
public class empCrudServlet extends HttpServlet {
    PersistenceManager pm = PMF.get().getPersistenceManager();   // 【1】
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws IOException {
        resp.setContentType("text/plain");
        resp.setCharacterEncoding("utf-8");
        String empno = req.getParameter("empno");
        
        String out = "";
        Query query = pm.newQuery(empmas.class);        // 【2】
        query.setFilter("empno == empnoParam");          // 【3】
        query.declareParameters("String empnoParam");    // 【4】
        try {
            List<empmas> results = (List<empmas>) query.execute(empno);   // 【5】
            if (results.iterator().hasNext()) {
                for (empmas e : results) {
                    out += e.getEmpname()+"<i>";
                    out += e.getDepart()+"<i>";
                    out += e.getSection()+"<i>";
                    out += e.getDate()+"<i>";
                    out += "参照成功 社員番号="+empno;
                    resp.getWriter().println(out);
                }
            } else {
                resp.getWriter().println("NO<i>:参照失敗 社員番号="+empno); 
            }
        } finally {
            query.closeAll();
        }       
    }
    
    public void doPost(HttpServletRequest req, HttpServletResponse resp)
    throws IOException {
        resp.setContentType("text/plain");
        resp.setCharacterEncoding("utf-8");
        
        String mode = req.getParameter("mode");
        String empno = req.getParameter("empno");
        String empname = req.getParameter("empname");
        String depart = req.getParameter("depart");
        String section = req.getParameter("section");
        
        if(mode.equals("add")){
            Date date = new Date();
            empmas emas = new empmas(empno, empname, depart, section, date);
            PersistenceManager pm = PMF.get().getPersistenceManager();
            try {
                pm.makePersistent(emas);
                resp.getWriter().println("OK:登録成功  社員番号="+empno);
            } catch(Exception e){
                resp.getWriter().println("NO:登録失敗 Error: " + e);
            } 
        }else if(mode.equals("upd")){
            Date date = new Date();
            try {
                empmas e = pm.getObjectById(empmas.class, empno);   //【6】
                e.setEmpname(empname);
                e.setDepart(depart);                               //【7】
                e.setSection(section);
                e.setDate(date);
            }catch (Exception e){
                resp.getWriter().println("NO:更新失敗 Error:"+e);
            } finally {
                pm.close();                                       //【8】
                resp.getWriter().println("OK:更新成功 社員番号=" + empno);
                pm = PMF.get().getPersistenceManager();             // 【9】
            }
        }else if(mode.equals("del")){
            try {
                empmas emas = pm.getObjectById(empmas.class, empno);  //【10】
                pm.deletePersistent(emas);                            //【11】
                resp.getWriter().println("OK:削除成功  社員番号=" + empno);
            }catch (Exception e){
                resp.getWriter().println("NO:削除失敗   Error:" + e);
            }
        }
    }
}
リスト5 empCrudServlet.java

「メソッド名スタイル」での参照

 JDOの参照には、前回見てきたSQLライクのJDOQLを使う方法のほかにも、いくつかの処理形式があります。リスト5では、その中でも「メソッド名スタイル」での参照方式になっています。

 この方式では、最初に【1】で各メソッド共通に使用されるPersistenceManagerクラスのインスタンスpmを生成しておき、次に【2】で、生成したpmのメソッドnewQueryの引数にリストで生成してあるempmas.classを指定してクエリオブジェクト(query)を生成します。

 特徴的なのは、その後の【3】と【4】です。この2行で、【5】で実行されるquery.executeの引数を指定しています。検索結果はコレクション形式でresultsにセットされます。if文以下のイテレータ処理は前回と同様ですが、このサンプルの場合はユニークキー指定の検索なので、処理データは1件のみです。

 なお、クライアントに送信するデータ項目ごとに""が追加されていますが、これはリスト2の受信処理で使用されています。

登録

 登録の場合は、データ項目が異なるだけで前回の処理方式とまったく同じですので問題ないと思います。

更新

 今回初めて出てきた処理は更新と削除です。更新については、「Googleの巨大データストアでは、その用途や構成などから更新処理はできないのでは」と一部ではいわれていたこともありました。しかしBigtableでは、このサンプルにあるように更新も、もちろん削除処理も可能です。

 JDOでオブジェクトを更新する場合は、getObjectByIdメソッドのより、第1引数指定のオブジェクトから第2引数指定のキーでエンティティ(≒レコード)をフェッチし、オブジェクトがオープン状態の間に、プロパティ値(データ項目)を更新します。そして、このようにして更新された内容はPersistenceManagerがクローズされるときに永続化されるのです。

 具体的には、リスト5の【6】で更新対象のエンティティをフェッチし、【7】では、データクラスempmasに定義したアクセサ(セッター)メソッドでプロパティ値を更新し、最後に【8】でpmをクローズすることによって、更新内容が永続化されます。

 このように更新処理では、pmインスタンスをクローズする必要があるので、更新処理後に【9】で再度pmインスタンスを生成して、次の処理に備える必要があります。

削除

 削除はシンプルな処理手順で、更新の場合と同じように【10】で削除対象のエンティティをフェッチし、【11】でフェッチしたエンティティ(empmas)を引数指定してdeletePersistentメソッドを実行することによって削除処理は完了します。

BigtableでRDBのJOINをカバーするには?

 次回はBigtableの操作について、もう1つ新しい機能を紹介したいと思います。Bigtableでは、テーブルのJOIN(結合)検索に対応する機能はありませんが、それをある程度カバーする機能があります。RDBのテーブルに対応するBigtableのオブジェクトでは、各データ項目を任意の数のコレクション形式にできるのです。つまり、データ項目を配列のように扱うことができ、リストとして処理できます

 次回は、このようなデータオブジェクトでのコレクションの扱いを、サンプルを例に見ていきます。

 また、AjaxではjQueryのほかにサーバリモーティング機能のDWR(Direct Web Remoting)を追加していきます。DWRについて詳しく知りたい読者は、下記記事を参照しておいてください。また拙著「Ajaxによる業務アプリケーション開発」(秀和システム)にも、DWRについて詳しく解説されているので、興味のある方は参照してみてください。次回も楽しみに。


前のページへ 1|2|3|4       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。