こんにちは。きんくまです。
今回はAIRを使ってDBに挑戦してみようと思います。
私のDBスペックは、DBは業務で全く使ったことがなく、ちょびっと知識をかじったぐらい。
↓今回つくるやつ。テキスト入力欄にSQL文を書いてSQL実行ボタンを押すと一覧が表示されます。
今回の参考書です。
>> SQLの書き方のツボとコツがゼッタイにわかるドリル本―最初からそう教えてくれればいいのに!
>> Adobe AIR クックブック ―プロフェッショナルに学ぶRIAプログラミングの実践
データベースって何?
・簡単にいうと、表組みデータ(エクセルみたいの)。
・それを検索しやすくしたもの。
だと理解。
AIRには、データベースのSQLiteを使うことができるので、それを使って学習してみようと
思いました。
データベースを使う方法
1)データベースを作る(SQLiteの場合は1つのファイル)
2)データベースに接続する
3)テーブルを作る(1つのデータベースにいくつでも作れる)
4)テーブルにデータを挿入・更新・検索する
となります。それで、これをためせるプログラムを作りました。
AIR本を参考にいろいろと書き加えました。
Flex4が出てネット上でもニュースになってるので、
家にあったもののほとんど使ってなかったFlex3を使ってみました。
なんでmxmlです。
table情報を取得する方法がAIR本に載ってなかったので、ASDocから調べたらなんかできました。
loadSchema()やってから、getSchemaResult()やるみたい。
普通のSQLだとtable情報を調べるのもSQL文を書くんだけど、AIRはちょっとばかし
勝手が違うみたい。
■データベースのユーティリティクラス(ArrayCollectionをArrayに変更すれば普通のflaでも使用できます)
package { import flash.data.SQLConnection; import flash.data.SQLResult; import flash.data.SQLSchemaResult; import flash.data.SQLStatement; import flash.data.SQLTableSchema; import flash.events.Event; import flash.events.EventDispatcher; import flash.events.SQLErrorEvent; import flash.events.SQLEvent; import flash.filesystem.File; import mx.collections.ArrayCollection; public class DBUtil extends EventDispatcher { private var _myDB:File; private var _isOpen:Boolean = false; private var _dbConn:SQLConnection; private var _resultArrayCollection:ArrayCollection; public static const ASYNC_CONNECT_COMPLETE:String = "async_connect_complete"; public static const ASYNC_SQL_COMPLETE:String = "async_sql_complete"; public static const SCHEMA_COMPLETE:String = "schema_complete"; public function get myDB():File { return _myDB; } public function get isOpen():Boolean { return _isOpen; } public function get resultArrayCollection():ArrayCollection { return _resultArrayCollection; } public function DBUtil() { createLocalDB(); } public function createLocalDB():void { var folder:File = File.applicationStorageDirectory.resolvePath('db'); folder.createDirectory(); _myDB = folder.resolvePath('myDBFile.db'); openLocalDB(_myDB, true); } public function openLocalDB(dbFile:File, isAsync:Boolean):void { _dbConn = new SQLConnection(); if(isAsync){ _dbConn.openAsync(dbFile); _dbConn.addEventListener(SQLEvent.OPEN, sqlOpenHD); _dbConn.addEventListener(SQLErrorEvent.ERROR, sqlOpenErrorHD); }else{ try{ _dbConn.open(dbFile); }catch(e:SQLErrorEvent){ trace('SQL Error: ' + e.error.message); trace('SQL Error Detail: ' + e.error.details); } } } public function sqlOpenHD(e:SQLEvent):void { _isOpen = true; dispatchEvent(new Event(ASYNC_CONNECT_COMPLETE)); } public function sqlOpenErrorHD(e:SQLErrorEvent):void { _dbConn.removeEventListener(SQLEvent.OPEN, sqlOpenHD); _dbConn.removeEventListener(SQLErrorEvent.ERROR, sqlOpenErrorHD); //trace('SQL Error: ' + e.error.message); //trace('SQL Error Detail: ' + e.error.details); dispatchEvent(e); } public function sqlExcuteErrorHD(e:SQLErrorEvent):void { var state:SQLStatement = e.target as SQLStatement; state.removeEventListener(SQLEvent.RESULT, sqlStatementResultHD); state.removeEventListener(SQLErrorEvent.ERROR, sqlExcuteErrorHD); //trace('SQL Error: ' + e.error.message); //trace('SQL Error Detail: ' + e.error.details); dispatchEvent(e); } public function executeSQLState(sqlText:String):void { if(isOpen == false){ throw new Error('DB is not connected.'); return; } var state:SQLStatement = new SQLStatement(); state.sqlConnection = _dbConn; state.text = sqlText; state.addEventListener(SQLEvent.RESULT, sqlStatementResultHD); state.addEventListener(SQLErrorEvent.ERROR, sqlExcuteErrorHD); state.execute(); } private function sqlStatementResultHD(e:SQLEvent):void { var state:SQLStatement = e.target as SQLStatement; state.removeEventListener(SQLEvent.RESULT, sqlStatementResultHD); state.removeEventListener(SQLErrorEvent.ERROR, sqlExcuteErrorHD); var result:SQLResult = state.getResult(); var temp:Array = result.data is Array ? result.data : [{rows:result.rowsAffected}]; _resultArrayCollection = new ArrayCollection(temp); dispatchEvent(new Event(ASYNC_SQL_COMPLETE)); } public function getTableInfo():void { _dbConn.addEventListener(SQLEvent.SCHEMA, sqlSchemaCompHD); _dbConn.addEventListener(SQLErrorEvent.ERROR, sqlSchemaErrorHD); _dbConn.loadSchema(); } private function sqlSchemaCompHD(e:SQLEvent):void { _dbConn.removeEventListener(SQLEvent.SCHEMA, sqlSchemaCompHD); _dbConn.removeEventListener(SQLErrorEvent.ERROR, sqlSchemaErrorHD); var result:SQLSchemaResult = _dbConn.getSchemaResult(); var tables:Array = result.tables; var temp:Array = []; for each(var tableSchema:SQLTableSchema in tables){ temp.push({ database:tableSchema.database, name:tableSchema.name, sql:tableSchema.sql, columns:tableSchema.columns.length }); } _resultArrayCollection = new ArrayCollection(temp); dispatchEvent(new Event(SCHEMA_COMPLETE)); } private function sqlSchemaErrorHD(e:SQLErrorEvent):void { _dbConn.removeEventListener(SQLEvent.SCHEMA, sqlSchemaCompHD); _dbConn.removeEventListener(SQLErrorEvent.ERROR, sqlSchemaErrorHD); //trace('SQL Error: ' + e.error.message); //trace('SQL Error Detail: ' + e.error.details); dispatchEvent(e); } } }
■そして、これを使う用のMXML
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="620" height="420"> <mx:Script> <![CDATA[ import mx.controls.Alert; import mx.collections.ArrayCollection; private var _dbUtil:DBUtil; [Bindable] private var _myResultAC:ArrayCollection; private function init():void { excuteBtn.addEventListener(MouseEvent.CLICK, excuteSQLBtnClickHD); tableInfoBtn.addEventListener(MouseEvent.CLICK, tableInfoBtnClickHD); _dbUtil = new DBUtil(); _dbUtil.addEventListener(DBUtil.ASYNC_CONNECT_COMPLETE, dbAsyncCompHD); } private function tableInfoBtnClickHD(e:MouseEvent):void { _dbUtil.addEventListener(DBUtil.SCHEMA_COMPLETE, dbSchemaCompHD); _dbUtil.addEventListener(SQLErrorEvent.ERROR, dbSchemaErrorHD); _dbUtil.getTableInfo(); } private function dbSchemaErrorHD(e:SQLErrorEvent):void { _dbUtil.removeEventListener(DBUtil.SCHEMA_COMPLETE, dbSchemaCompHD); _dbUtil.removeEventListener(SQLErrorEvent.ERROR, dbSchemaErrorHD); Alert.show(e.error.message + '\n' + e.error.details); } private function dbSchemaCompHD(e:Event):void { _dbUtil.removeEventListener(DBUtil.SCHEMA_COMPLETE, dbSchemaCompHD); _dbUtil.removeEventListener(SQLErrorEvent.ERROR, dbSchemaErrorHD); _myResultAC = _dbUtil.resultArrayCollection; //Alert.show('table schema read complete'); } private function excuteSQLBtnClickHD(e:MouseEvent):void { _dbUtil.addEventListener(DBUtil.ASYNC_SQL_COMPLETE, dbSQLCompleteHD); _dbUtil.addEventListener(SQLErrorEvent.ERROR, dbSQLErrorHD); _dbUtil.executeSQLState(sqlInputTxt.text); } private function dbSQLErrorHD(e:SQLErrorEvent):void { _dbUtil.removeEventListener(DBUtil.ASYNC_SQL_COMPLETE, dbSQLCompleteHD); _dbUtil.removeEventListener(SQLErrorEvent.ERROR, dbSQLErrorHD); Alert.show(e.error.message + '\n' + e.error.details); } private function dbSQLCompleteHD(e:Event):void { _dbUtil.removeEventListener(DBUtil.ASYNC_SQL_COMPLETE, dbSQLCompleteHD); _dbUtil.removeEventListener(SQLErrorEvent.ERROR, dbSQLErrorHD); _myResultAC = _dbUtil.resultArrayCollection; //Alert.show('SQL excuted !'); } private function dbAsyncCompHD(e:Event):void { Alert.show("SQL connection complete !"); } ]]> </mx:Script> <mx:Panel x="0" y="0" width="588" height="388" layout="absolute" title="SQLTest" initialize="init();"> <mx:DataGrid x="10" y="111" width="548" height="227" id="myDG" dataProvider="{_myResultAC}"/> <mx:Button x="10" y="81" label="SQL実行" id="excuteBtn"/> <mx:Button x="88" y="81" label="table情報" id="tableInfoBtn"/> <mx:TextArea x="10" y="10" width="548" height="63" id="sqlInputTxt" wordWrap="true" editable="true"/> </mx:Panel> </mx:WindowedApplication>
解説
1)データベースを作る(SQLiteの場合は1つのファイル)
2)データベースに接続する
の部分は、
public function createLocalDB():void { var folder:File = File.applicationStorageDirectory.resolvePath('db'); folder.createDirectory(); _myDB = folder.resolvePath('myDBFile.db'); openLocalDB(_myDB, true); } public function openLocalDB(dbFile:File, isAsync:Boolean):void { _dbConn = new SQLConnection(); if(isAsync){ _dbConn.openAsync(dbFile); _dbConn.addEventListener(SQLEvent.OPEN, sqlOpenHD); _dbConn.addEventListener(SQLErrorEvent.ERROR, sqlOpenErrorHD); }else{ try{ _dbConn.open(dbFile); }catch(e:SQLErrorEvent){ trace('SQL Error: ' + e.error.message); trace('SQL Error Detail: ' + e.error.details); } } }
で、1つのDB用のファイル(myDBFile.db)を作って、同期か非同期で開くという感じです。
mxmlの方は起動したら、すでにここまでやってある状態にしました。
3)テーブルを作る(1つのデータベースにいくつでも作れる)
はテキスト入力欄に
CREATE TALBE test1( id INTEGER PRIMARY KEY, name TEXT, phone TEXT );
とか入力して、SQL実行ボタンを押せばテーブルが作成されます。
それで、ここでもAIR仕様があって、AIRのSQLiteでは使用可能な型がちょびっと変わってるみたいです。
>> ローカルデータベースでの SQL サポート – Adobe® Flex™ 3.2 リファレンスガイド データ型のサポート
SQL本によれば、INT型とかVARCHAR型とかいうのがあるみたいなんですけど、
AIRのSQLiteだとINTEGER型、TEXT型というふうになっとります。
tableをうまく作成したら、table情報ボタンをおします。そしたら、↓の画面のようになったらOK
4)テーブルにデータを挿入・更新・検索する
テーブルができたんで、データをいれてみましょう。
INSERT INTO test1 VALUES(null, '佐藤', '0123-45-6789');
とやってSQL実行ボタンをおして、エラーがでなければ成功
データを確認します。
SELECT * FROM test1;
とやって、一覧がでてきたらOKです。
注意点
AIRのSQLは他のSQLとは違う部分があるので、SQL文がうまく通らないなあと
思ったときは、下の仕様書のページで確認してみたほうがよさそうです。
■ 自作iPhoneアプリ 好評発売中!
・フォルメモ - シンプルなフォルダつきメモ帳
・ジッピー電卓 - 消費税や割引もサクサク計算!
■ LINEスタンプ作りました!
毎日使える。とぼけたウサギ