データベースの作成
AIRランタイムにはSQLiteというオープンソースのデータベース機能が組み込まれており、
データベースは単一のローカルファイルを使用します。このファイルには可搬性があり、
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="openDB()">
<mx:Script>
<![CDATA[
private function openDB():void {
var db:File = File.desktopDirectory.resolvePath("sample.db");
var conn:SQLConnection = new SQLConnection();
conn.addEventListener(SQLEvent.OPEN, openHandler);
conn.addEventListener(SQLErrorEvent.ERROR, errorHandler);
conn.openAsync(db);
}
private function openHandler(e:SQLEvent):void {
trace("DBをオープンしました");
}
private function errorHandler(e:SQLErrorEvent):void {
trace(e.error.message);
}
]]>
</mx:Script>
</mx:WindowedApplication>
上記のコードを実行すると、
なお、
SQLの実行
データベースに対する操作はSQLで行います。SQLを実行するにはSQLStatementオブジェクトを使います。次のコードはテーブルを作成するサンプルです。データベースsample.
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="openDB()">
<mx:Script>
<![CDATA[
private var _conn:SQLConnection;
private function openDB():void {
var db:File = File.desktopDirectory.resolvePath("sample.db");
_conn = new SQLConnection();
_conn.addEventListener(SQLEvent.OPEN, openHandler);
_conn.addEventListener(SQLErrorEvent.ERROR, errorHandler);
_conn.openAsync(db);
}
private function openHandler(e:SQLEvent):void {
createTable();
}
private function errorHandler(e:SQLErrorEvent):void {
trace(e.error.message);
}
private function createTable():void {
var sql:SQLStatement = new SQLStatement();
sql.sqlConnection = _conn;
sql.text =
"CREATE TABLE IF NOT EXISTS menu (" +
" food TEXT," +
" price NUMERIC" +
")";
sql.addEventListener(SQLEvent.RESULT, resultHandler);
sql.addEventListener(SQLErrorEvent.ERROR, errorHandler);
sql.execute();
}
private function resultHandler(e:SQLEvent):void {
trace("テーブル作成済み");
}
]]>
</mx:Script>
</mx:WindowedApplication>
上のサンプルではcreateTable()メソッド内でSQLを実行しています。SQLStatementオブジェクトのsqlConnectionプロパティには実行対象のデータベースを指定します。値はSQLConnectionオブジェクトです。その上でtextプロパティにSQL文を設定し、
レコードの操作結果
レコードの挿入や抽出等の操作を行った場合も、
private var _conn:SQLConnection;
private var _sql:SQLStatement;
/* データベースへの接続処理等は省略 */
private function insertRecords():void {
_sql = new SQLStatement();
_sql.sqlConnection = _conn;
_sql.text = "INSERT INTO menu (food, price) VALUES ('牛丼', 280)";
_sql.addEventListener(SQLEvent.RESULT, insertResultHandler);
_sql.execute();
}
private function insertResultHandler(e:SQLEvent):void {
var result:SQLResult = _sql.getResult();
trace(result.lastInsertRowID);
}
コードから分かるように、
次のコードはpriceカラムが100以下のレコードを抽出する例です。
private var _conn:SQLConnection;
private var _sql:SQLStatement;
/* データベースへの接続処理等は省略 */
private function selectRecords():void {
_sql = new SQLStatement();
_sql.sqlConnection = _conn;
_sql.text = "SELECT * FROM menu WHERE price <= 100";
_sql.addEventListener(SQLEvent.RESULT, selectResultHandler);
_sql.execute();
}
private function selectResultHandler(e:SQLEvent):void {
var result:SQLResult = _sql.getResult();
var records:Array = result.data;
if (records != null) {
trace(records.length + "件ヒットしました");
for each (var item:* in records) {
trace(item.food, item.price);
}
} else {
trace("ヒットなし");
}
}
今度はSQLResultオブジェクトのdataプロパティを取得しています。これは抽出したレコードの配列です。各要素はカラム名をプロパティとするObjectオブジェクトです。レコードが1件も一致しなかった場合、
抽出結果を分割して受け取る
抽出条件に一致するレコードが多数ある場合、
private var _conn:SQLConnection;
private var _sql:SQLStatement;
/* データベースへの接続処理等は省略 */
private function selectRecords():void {
_sql = new SQLStatement();
_sql.sqlConnection = _conn;
_sql.text = "SELECT * FROM menu WHERE price <= 100";
_sql.addEventListener(SQLEvent.RESULT, selectResultHandler);
_sql.execute(10);
}
private function selectResultHandler(e:SQLEvent):void {
var result:SQLResult = _sql.getResult();
var records:Array = result.data;
if (records != null) {
trace(records.length + "件ヒットしました");
for each (var item:* in records) {
trace(item.food, item.price);
}
if (!result.complete) {
_sql.next(10);
}
} else {
trace("ヒットなし");
}
}
上のコードのようにexecute()メソッドのパラメータに件数を指定することで、
SQL文でパラメータを使う
データベース操作では何度も同じSQL文を使うことがあります。SQL文は実行時にコンパイルが必要なため、
また、
_sql.text = "INSERT INTO menu (food, price) VALUES (@food, @price)";
_sql.parameters["@food"] = "カレー丼";
_sql.parameters["@price"] = 400;
_sql.execute();
SQL文の中にはプレースホルダとして@を付けたパラメータ名を記述しておきます。@の代わりに:を使うこともできます。その上で、
また、
_sql.text = "INSERT INTO menu (food, price) VALUES (?, ?)";
_sql.parameters[0] = "カレー丼";
_sql.parameters[1] = 400;
_sql.execute();
トランザクション
トランザクションを開始するにはSQLConnectionオブジェクトのbegin()メソッドを使います。トランザクション処理が正しく完了したらcommit()メソッドで変更内容を確定し、
private var _conn:SQLConnection;
private var _sql:SQLStatement;
private var _dat:Array;
/* データベースへの接続処理等は省略 */
private function beginTransaction():void {
_conn.addEventListener(SQLEvent.BEGIN, beginHandler);
_conn.addEventListener(SQLEvent.COMMIT, commitHandler);
_conn.addEventListener(SQLEvent.ROLLBACK, rollbackHandler);
_conn.addEventListener(SQLErrorEvent.ERROR, errorHandler);
_conn.begin();
}
private function beginHandler(e:SQLEvent):void {
_dat = [{food:"焼き鳥丼", price:450},
{food:"玉子", price:50},
{food:"味噌汁", price:50}];
_sql = new SQLStatement();
_sql.sqlConnection = _conn;
_sql.text = "INSERT INTO menu (food, price) VALUES (?, ?)";
_sql.addEventListener(SQLEvent.RESULT, insertResultHandler);
_sql.addEventListener(SQLErrorEvent.ERROR, insertErrorHandler);
insertRecord();
}
private function insertRecord():void {
var item:Object = _dat.shift();
_sql.parameters[0] = item.food;
_sql.parameters[1] = item.price;
_sql.execute();
}
private function insertResultHandler(e:SQLEvent):void {
if (!_dat.length) {
_conn.commit();
} else {
insertRecord();
}
}
private function insertErrorHandler(e:SQLErrorEvent):void {
_conn.rollback();
}
private function commitHandler(e:SQLEvent):void {
trace("コミット完了");
}
private function rollbackHandler(e:SQLEvent):void {
trace("ロールバック完了");
}
private function errorHandler(e:SQLErrorEvent):void {
trace(e.error.message);
}
SQLiteではINSERTやUPDATE、
なお、
SQLite用ツールの利用
テスト用にデータベースを用意したりちょっとした内容確認をしたいときなどは、
