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

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

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

【3】データの削除

 次に、テーブル作成成功後の処理(sqlStatementCreateResultHandler)を見ていきます。

    private function sqlStatementCreateResultHandler(
        event:SQLEvent):void {
        trace(MessageConsts.
            MESSAGE_SQLITE_TABLE_CREATION_SUCCESS);
        deleteRecord();
    }

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

    public function deleteRecord():void {
        // 既存データが存在していた場合、いったん削除します。
        sqlStatement = new SQLStatement();
        sqlStatement.sqlConnection = sqlConnection;
        sqlStatement.text = "DELETE FROM USER";
    
        //イベント登録
        sqlStatement.addEventListener(SQLEvent.RESULT,
            sqlStatementDeleteResultHandler);
        sqlStatement.addEventListener(SQLErrorEvent.ERROR,
            sqlStatementErrorHandler);
    
        //実行
        sqlStatement.execute();
    }

 ここでは、サーバから取得したデータを挿入する前に、既存データが存在していた場合に既存データをすべて削除してテーブルを空にしています。処理の流れはCREATE文実行のときとまったく同じですね。

【4】データの挿入

 続いて、テーブルデータ削除成功後の処理(sqlStatementDeleteResultHandler)を見ていきます。

    private function sqlStatementDeleteResultHandler(
        event:SQLEvent):void {
        trace(MessageConsts.MESSAGE_SQLITE_DATA_DELETION_SUCCESS);
        insertRecord();
    }

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

    private function insertRecord():void {
        // インデックスをメソッド間で共有できるように保存
        loopIndex = 0;
        loopIndexLimit = userList.length;
    
        // トランザクション開始
        sqlConnection.begin();
    
        sqlStatement = new SQLStatement();
        sqlStatement.sqlConnection = sqlConnection;
    
        // イベント登録
        sqlStatement.addEventListener(SQLEvent.RESULT,
            sqlStatementInsertResultHandler);
        sqlStatement.addEventListener(SQLErrorEvent.ERROR,
            sqlStatementErrorHandler);
    
        // 1件目のINSERT処理に移ります。
        insert();
    }

 これ以降は3つのメソッドが連携して1万回のINSERT処理を実行しています。上記insertRecordは初期処理を行って1回目のINSERT実行をinsert()メソッドに依頼しています。これまでとの違いは、最初にトランザクションを開始しているところです。

 これにより、SQL失敗時にロールバックしたりといったことが可能です。また、トランザクションを開始しない場合、毎回の処理でコミット処理が実行=データベースファイルへの書き込み処理が発生し、著しいパフォーマンス低下が発生します。

 実際のINSERT処理を担当するinsert()は以下のようになります。

    private function insert():void {
        // Insertするデータ
        var user:User = User(userList.getItemAt(loopIndex));
    
        // SQLです。
        var mySQL:String = "INSERT INTO USER(name, ruby, mail,"
            +" sex, age, birthday, married, bloodtype, prefecture, "
            +"prefectureCode, phone, keitai, carrier, curry) "
            + "VALUES(:name, :ruby, :mail, :sex, :age, :birthday,"
            +" :married, :bloodtype, :prefecture, :prefectureCode, "
            +":phone, :keitai, :carrier, :curry)";
    
        sqlStatement.parameters[":name"] = user.name;
        sqlStatement.parameters[":ruby"] = user.ruby;
        sqlStatement.parameters[":mail"] = user.mail;
        sqlStatement.parameters[":sex"] = user.sex;
        sqlStatement.parameters[":age"] = user.age;
        sqlStatement.parameters[":birthday"] = user.birthday;
        sqlStatement.parameters[":married"] = user.married;
        sqlStatement.parameters[":bloodtype"] = user.bloodtype;
        sqlStatement.parameters[":prefecture"] = user.prefecture;
        sqlStatement.parameters[":prefectureCode"]=user.prefectureCode;
        sqlStatement.parameters[":phone"] = user.phone;
        sqlStatement.parameters[":keitai"] = user.keitai;
        sqlStatement.parameters[":carrier"] = user.carrier;
        sqlStatement.parameters[":curry"] = user.curry;
    
        sqlStatement.text = mySQL;
    
        //実行
        sqlStatement.execute();
    }

 この処理のポイントは、「パラメータ化されたSQL」です。多くのデータベースアクセスフレームワーク同様にSQLを文字列連携で作成するのではなく、SQL文内にパラメータを設定し外部から値を設定することがSQLiteでも可能です。

 パラメータはコロン(:)またはアットマーク(@)から始まるパラメータ名でしています。クエスチョンマーク(?)でも指定が可能ですが、前者がSQLStatementに対してパラメータ名によって値を設定するのに対して、後者はインデックス(parameters[0]、……、parameters[n])で値を設定します。

 今回のサンプルアプリケーションでは、前者で設定しています。このパラメータ指定の構文を採用することにより、SQLに対してSQLインジェクション対策がSQLStatementクラス側で自動的に行われます。

 次に1件1件のINSERT処理の結果イベント(sqlStatementInsertResultHandler)を見ていきます。

    private function sqlStatementInsertResultHandler(
        event:SQLEvent):void {
        loopIndex++;
    
        // 処理状況により引き続きInsertするかどうかをチェック
        if(loopIndex < loopIndexLimit) {
            insert();
        } else {
            Alert.show(MessageConsts.
                MESSAGE_SQLITE_DATA_INSERTION_SUCCESS);
    
            // [loopIndexLimit]件分の処理を一気にコミット
            sqlConnection.commit();
    
            // 後処理
            initDisplay2();
        }
    }

 この処理は単にinsert()メソッドを1万回しているだけです。1万回実行後に、SQLをコミットして、後処理につなげています。後処理ではビジーカーソルを元に戻して、画面上部のボタンを押せるように元に戻しています。

SQLiteの可能性は体験してから探ろう

 このようなSQLを実行するということは、HTMLやFlexアプリケーションを作成するほとんどの方はいままでやらなかったと思います。

 AIRでは、クライアントアプリケーションが直接内蔵のデータベースに対してSQL経由でやりとりできるのです。いろいろな用途にSQLiteは応用できる可能性を秘めているので、まずは皆さん実際にアプリケーションを動かしてSQLiteの機能を体験してみてください。

データをXML形式ファイルとしてデスクトップへ保存

 次に、AIRの特徴的な処理である「ファイルアクセス」の例として、ファイル書き出し処理の部分を見ていきます。UserLogicクラスのxmlButtonClickHandlerからの一連の処理がXML書き出し処理です。処理の流れは以下のようになります。

 次ページからは、それぞれの処理の詳細を見ていきましょう。そして、最後にAIRを採用する場合によく問題点に挙げられることについて触れ、連載を締めくくりたいと思います。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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