連載
» 2008年11月12日 00時00分 公開

動かして試すAdobe AIR+Javaアプリの“可能性”業務用RIAの本命!? Flex+Java開発入門(6)(2/4 ページ)

[福田寅成,クラスメソッド株式会社]

AIR独自の機能を1万件データ表示アプリに追加

 今回提供したサンプルアプリケーションでは、「HelloWorldアプリケーション」「クイズ/eラーニングアプリケーション」はFlex版と同じ挙動ですが、「1万件データ表示アプリケーション」はAIR版独自の機能を追加してあります。

図1 AIR版1万件データ表示アプリケーション(画像をクリックすると、拡大します) 図1 AIR版1万件データ表示アプリケーション(画像をクリックすると、拡大します)

 前回からの画面構成や一覧表示機能には変化はないですが、上部のボタン群がボタン1個から3個に増えています。

AIRならではの機能を追加

 このアプリケーションでは以下の機能を提供しています。

 後ろ2つの機能が新機能です。上部のボタン群を順にクリックしていくことで3つの処理が順番に走ります。

 処理中に画面上では特に大きな変化はありませんが、それぞれの処理中にデバッグコンソールに処理状況が出力され、最後のXML書き出し処理が成功すると、デスクトップに「users.xml」というXMLファイルが生成されます。画面上のDataGridに表示されているデータを丸ごとエクスポートしたような感じです。

アプリケーションの全体像と処理の流れ

 今回のアプリケーションの処理の流れとアーキテクチャは図2のようになります。

図2 AIR版1万件データ表示アプリケーション全体像(画像をクリックすると、拡大します) 図2 AIR版1万件データ表示アプリケーション全体像(画像をクリックすると、拡大します)

 図2を見ても分かるように、デスクトップアプリケーションになってもアプリケーション構築の作法の基本は何も変わりません。Flexで利用可能なノウハウはまさに丸ごとAIRに持ってこれます。

 また、Javaサイドに目を向けると、クライアントがFlexかAIRかによって作りをまったく(100%)変えていません。もともとクライアント/サーバ間の通信がオブジェクト受け渡しのフォーマットであるAMFによって標準化されているので、その決まりに沿って作っていればクライアントの実行環境はどのようなものでもOKです。

 2008年11月現在、クライアントの実行環境としては、PC上のFlash PlayerとAIRが主流といえますが、今後モバイル端末や組み込み機器にAIRが載ってきたりしても、サーバ側はほぼ同じ作りでよいことになります(クライアントのメモリの状況で送受信するデータのサイズを制限したりするといった処理は入るかもしれません)。

 逆に上記アーキテクチャで赤い四角に囲まれている部分に対する処理がAIR独自の処理です。次に、これら2つの独自処理部分の解説に移ります。

サーバから取得したデータをローカルDBへ挿入

 UserLogicクラスのsqliteButtonClickHandlerからの一連の処理がSQLiteデータベースへのデータ挿入処理です。処理の流れは、以下のようになります。

 では、それぞれの処理の詳細を見ていきましょう。

【1】DB(ファイル)の新規作成と接続の確立

 この処理についてのソースコードは以下になります。

    public function sqliteButtonClickHandler(event:MouseEvent):void {
        // 利用可処理
        view.controlBar.enabled = false;
    
        // ビジーカーソル表示
        CursorManager.setBusyCursor();
    
        // データベースを開きます。存在しない場合は新規作成されます
        var dbFile:File = new File(        
            File.applicationDirectory.nativePath
            + "/data/atmarkit.db");
    
        // SQLConnectionを新規作成します。
        sqlConnection = new SQLConnection();
    
        // イベント登録
        sqlConnection.addEventListener(SQLEvent.OPEN,
            sqlConnectionOpenHandler);
        sqlConnection.addEventListener(SQLErrorEvent.ERROR,         sqlConnectionErrorHandler);
    
        // openAsync()によってデータベースを開きます。
        sqlConnection.openAsync(dbFile);
    }

 最初に、画面上部のボタンを利用不可にして、マウスカーソルを、処理中を表す「ビジーカーソル」に変更します。その後、データベースファイルへの参照を作成します。ファイルがない場合、この処理は新規作成処理になります。

 File.applicationDirectory.nativePathはアプリケーションのインストールディレクトリを表します。その下の「data」フォルダ内のatmarkit.dbを参照しています。この参照の記述で分かるように、SQLiteのデータベースはシンプルなファイルシステムベースのデータベースです。

 次に、SQLConnectionを作成し、コネクション接続成功、失敗時のイベントハンドラを設定します。準備ができたら、SQLConnectionに対してコネクションを開く処理(ここでは、openAsync)を実行します。

 この流れを見て気付く方もいると思いますが、RemoteObjectを呼び出す流れとSQLiteへ処理を行う際の流れが非常に似ていることが分かります。Flex/AIRではこのように外部リソースへアクセスする際には非同期処理となり、その際の処理の流れは常に同じ様式になります。

 ただ、SQLiteへのアクセスの際に「同期処理」を選択することも可能です。この場合はSQLConnection#openを呼び出せばよく、その場合、openメソッドの直後にSQLコネクションが確立した後の処理を続けて記述できます(openAsyncで開いた場合の成功イベントに記述するような処理を、そのまま続けて記述できます)。

 今回はRemoteObjectとのやりとりと処理の流れを一致させるという意味合いもあって、SQLiteに非同期でアクセスするアプリケーションになっています。

【2】テーブルの新規作成

 次に、SQLコネクション確立成功後の処理(sqlConnectionOpenHandler)を見ていきます。

    private function sqlConnectionOpenHandler(event:SQLEvent):void {
        trace(MessageConsts.MESSAGE_SQLITE_CONNECTION_SUCCESS);
        createTable();
    }

 上記処理ではすぐにcreateTableメソッドを呼び出しています。createTableメソッドは以下のようになります。

    private function createTable():void {
        // テーブルを作成します
        sqlStatement = new SQLStatement();
        sqlStatement.sqlConnection = sqlConnection;
    
        // テーブルの作成
        sqlStatement.text =
            "CREATE TABLE IF NOT EXISTS USER (" +
            "id INTEGER PRIMARY KEY, " +
            "name TEXT, " +
            "ruby TEXT, " +
            "mail TEXT, " +
            "sex TEXT, " +
            "age TEXT, " +
            "birthday TEXT, " +
            "married TEXT, " +
            "bloodtype TEXT, " +
            "prefecture TEXT, " +
            "prefectureCode TEXT, " +
            "phone TEXT, " +
            "keitai TEXT, " +
            "carrier TEXT, " +
            "curry TEXT" +
        ")";
    
        // イベント登録
        sqlStatement.addEventListener(SQLEvent.RESULT,
            sqlStatementCreateResultHandler);
        sqlStatement.addEventListener(SQLErrorEvent.ERROR,
            sqlStatementErrorHandler);
    
        // 実行
        sqlStatement.execute();
}

 まず、SQLStatementオブジェクトを作成し、SQL文や成功/失敗イベントハンドラを設定し、SQLを実行します。処理の流れは、先ほどの処理【1】と同じような流れです。SQLステートメントを表すSQLStatementオブジェクトに先ほど確立したSQLConnectionオブジェクトを設定して、その後SQLを実行しています。

 また、上記処理は「テーブルがない場合は新規作成」となっているので、テーブルがデータベースに存在する場合は特に何も処理は行われず、成功イベントが呼び出されます。

 次ページでは引き続き、データの削除と挿入についても解説します。

注意! 「SQL内のテーブル名を小文字に」

上記テーブルの新規作成処理では、SQLに少し特徴があります。それは、SQL内のテーブル名が「小文字(キャメルケース)」になっていることです。これは、ActionScriptのUserクラスのプロパティの命名規則と同じものです。

命名規則をActionScriptとSQLiteのテーブルで一致させておくことにより、後術SELECT処理で重要な効果をもたらします。サーバサイドのJavaでの実装部分を含めると、アプリケーション全体で命名規則が一致することになります。

データベースのカラム名は大文字」に慣れている人には、最初はとっつきにくいと思います。しかし、すぐに慣れることなので、SQLiteを利用する際は、この命名規則に関して少し考慮するようにしてください。


Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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