Adobe AIR中使用Flex连接Sqlite数据库.docx
《Adobe AIR中使用Flex连接Sqlite数据库.docx》由会员分享,可在线阅读,更多相关《Adobe AIR中使用Flex连接Sqlite数据库.docx(19页珍藏版)》请在冰豆网上搜索。
AdobeAIR中使用Flex连接Sqlite数据库
(1)(创建数据库和表,以及同步和异步执行模式)
本章主要总结关系数据库引擎(sqlite),同步和异步执行模式,创建数据库和表
AdobeAIR包括一个基于SQL的关系数据库引擎(sqlite),该引擎在运行时中运行,数据以本地方式存储在运行AIR应用程序的计算机上的数据库文件中(例如,在计算机的硬盘驱动器上)。
由于数据库的运行和数据文件的存储都在本地进行,因此,不管网络连接是否可用,AIR应用程序都可以使用数据库。
单个AdobeAIR本地SQL数据库作为单个文件存储在计算机的文件系统中。
运行时包括SQL数据库引擎,该引擎管理数据库文件的创建和结构化以及操作和检索数据库文件中的数据。
运行时不指定在文件系统上存储数据库数据的方式或位置;相反,每个数据库完全存储在单个文件中。
您指定在文件系统中存储数据库文件的位置。
单个AIR应用程序可以访问一个或多个单独的数据库(即单独的数据库文件)。
由于运行时将每个数据库作为单个文件存储在文件系统上,因此可以在需要时按照应用程序的设计和操作系统的文件访问约束查找您的数据库。
每个用户都可以具有其特定数据的单独数据库文件,或者数据库文件可以由在单个计算机上共享数据的所有应用程序用户访问。
由于数据对单个计算机是本地的,因此在不同计算机上的用户之间并不自动共享数据。
本地SQL数据库引擎未提供对远程数据库或基于服务器的数据库执行SQL语句的任何功能。
关于sqlite
关于SQLite的特性:
1.ACID事务
2.零配置–无需安装和管理配置
3.储存在单一磁盘文件中的一个完整的数据库
4.数据库文件可以在不同字节顺序的机器间自由的共享
5.支持数据库大小至2TB
6.足够小,大致3万行C代码,250K
7.比一些流行的数据库在大部分普通数据库操作要快
8.简单,轻松的API
9.包含TCL绑定,同时通过Wrapper支持其他语言的绑定
10.良好注释的源代码,并且有着90%以上的测试覆盖率
11.独立:
没有额外依赖
12.Source完全的Open,你可以用于任何用途,包括出售它
13.支持多种开发语言,C,PHP,Perl,Java,ASP.NET,Python
更详细情况可以参考以下站点:
http:
//www.sqlite.org/
本地SQL数据库的用途
AIR本地SQL数据库功能可以用于将应用程序数据存储在用户的本地计算机上的任何目的。
AdobeAIR包括在本地存储数据的几种机制,各机制具有不同的优点。
以下是本地SQL数据库在AIR应用程序中的一些可能用途:
1.对于面向数据的应用程序(例如通讯簿),数据库可以用于存储主应用程序数据。
2.对于面向文档的应用程序(用户创建要保存并可能共享的文档),可以在用户指定的位置将每个文档另存为数据库文件。
(但是,请注意,任何AIR应用程序都能够打开数据库文件,因此对于潜在敏感的文档,建议使用单独的加密机制。
)
3.对于支持网络的应用程序,数据库可以用于存储应用程序数据的本地缓存,或者在网络连接不可用时暂时存储数据。
可以创建一种将本地数据库与网络数据存储同步的机制。
4.对于任何应用程序,数据库都可以用于存储单个用户的应用程序设置,例如用户选项或应用程序信息(如窗口大小和位置)。
关于同步和异步执行模式
1.编写代码以处理本地SQL数据库时,会指定以两种执行模式之一执行数据库操作:
异步或同步执行模式。
通常,代码示例说明如何以这两种方式执行每个操作,以便您可以使用最适合您需求的示例。
2.在异步执行模式中,为运行时提供一个指令,运行时将在请求的操作完成或失败时调度事件。
首先,通知数据库引擎执行操作。
在应用程序继续运行的同时,数据库引擎在后台工作。
最后,完成操作时(或者它失败时),数据库引擎调度事件。
由事件触发的代码执行后续操作。
此方法具有一个重要的优点:
运行时在后台执行数据库操作,同时主应用程序代码继续执行。
如果数据库操作花费大量的时间,则应用程序继续运行。
最重要的是,用户可以继续与其交互,而屏幕不会冻结。
但是,与其它代码相比,编写异步操作代码可能更加复杂。
在必须将多个相关的操作分配给各个事件侦听器方法的情况下,通常会出现此复杂性。
3.从概念上说,将操作作为单个步骤序列(一组同步操作,而不是分到几个事件侦听器方法中的一组操作)进行编码更为简单。
除了异步数据库操作外,AdobeAIR还允许您同步执行数据库操作。
在同步执行模式中,操作不在后台运行。
相反,它们以与所有其它应用程序代码相同的执行序列运行。
通知数据库引擎执行操作。
然后,代码在数据库引擎工作时暂停。
完成操作后,继续执行下一行代码。
4.异步还是同步执行操作是在SQLConnection级别上设置的。
使用单个数据库连接,无法同步执行某些操作或语句,同时异步执行其它操作或语句。
通过调用SQLConnection方法打开数据库,可以指定SQLConnection是在同步还是异步执行模式下操作。
如果调用SQLConnection.open(),则连接在同步执行模式下操作;如果调用SQLConnection.openAsync(),则连接在异步执行模式下操作。
使用open()或openAsync()将SQLConnection实例连接到数据库后,除非先关闭再重新打开到数据库的连接,否则该实例将固定为同步或异步执行模式。
创建数据库
若要创建数据库文件,请首先创建SQLConnection实例。
调用其open()方法在同步执行模式下打开它,或者调用其openAsync()方法在异步执行模式下打开它。
open()和openAsync()方法用于打开到数据库的连接。
如果传递的File实例引用reference参数(第一个参数)的不存在的文件位置,则open()或openAsync()方法将在该文件位置创建一个数据库文件,并打开到新创建的数据库的连接。
不管是调用open()方法还是openAsync()方法创建数据库,数据库文件的名称都可以是具有任何文件扩展名的任何有效文件名。
如果调用reference参数为null的open()或openAsync()方法,则将创建新的内存中数据库,而不是在磁盘上创建数据库文件。
以下代码清单说明使用异步执行模式创建数据库文件(新数据库)的过程,数据库文件保存在应用程序的存储目录中,其文件名为“myTestdb.db”:
importmx.controls.Alert;
privatevarcon:
SQLConnection;
privatefunctioninitApp():
void
{
varfile:
File=File.applicationStorageDirectory.resolvePath("myTestdb.db")
con=newSQLConnection();
//在openAsync()方法调用操作成功完成时调度
con.addEventListener(SQLEvent.OPEN,openHandler);
//SQLConnection对象的异步操作导致错误时调度
con.addEventListener(SQLErrorEvent.ERROR,errorHandler);
con.openAsync(file);
}
privatefunctionopenHandler(evt:
SQLEvent):
void
{
Alert.show("成功完成");
}
privatefunctionerrorHandler(evt:
SQLErrorEvent):
void
{
Alert.show("失败");
Alert.show(evt.error.message);
Alert.show(evt.error.details);
}
要同步执行操作,请在使用SQLConnection实例打开数据库连接时,调用open()方法。
以下代码说明如何创建和打开同步执行其操作的SQLConnection实例:
importmx.controls.Alert;
privatevarcon:
SQLConnection;
privatefunctioninitApp():
void
{
varfile:
File=File.applicationStorageDirectory.resolvePath("myTestdb.db")
con=newSQLConnection();
try
{
con.open(file);
Alert.show("成功完成");
}
catch(error:
SQLError)
{
Alert.show(error.message);
Alert.show(error.details);
}
}
创建数据库表
以下使用异步执行模式在现有数据库文件中创建一个名为“emp”的表。
importmx.controls.Alert;
privatevarcon:
SQLConnection;
privatevarcreateStmt:
SQLStatement;
privatefunctioninitApp():
void
{
varfile:
File=File.applicationStorageDirectory.resolvePath("myTestdb.db")
con=newSQLConnection();
//在openAsync()方法调用操作成功完成时调度
con.addEventListener(SQLEvent.OPEN,openHandler);
//SQLConnection对象的异步操作导致错误时调度
con.addEventListener(SQLErrorEvent.ERROR,errorHandler);
con.openAsync(file);
}
privatefunctioncreateResult(event:
SQLEvent):
void
{
Alert.show("表创建");
}
privatefunctioncreateError(event:
SQLErrorEvent):
void
{
Alert.show("Errormessage:
",event.error.message);
Alert.show("Details:
",event.error.details);
}
privatefunctionopenHandler(evt:
SQLEvent):
void
{
Alert.show("成功完成");
createStmt=newSQLStatement();
createStmt.sqlConnection=con;
varsql:
String=
"CREATETABLEIFNOTEXISTSemp("+
" empIdINTEGERPRIMARYKEYAUTOINCREMENT,"+
" firstNameTEXT,"+
" lastNameTEXT,"+
" salaryNUMERICCHECK(salary>0)"+
")";
createStmt.text=sql;
createStmt.addEventListener(SQLEvent.RESULT,createResult);
createStmt.addEventListener(SQLErrorEvent.ERROR,createError);
createStmt.execute();
}
privatefunctionerrorHandler(evt:
SQLErrorEvent):
void
{
Alert.show("失败");
Alert.show(evt.error.message);
Alert.show(evt.error.details);
}
以下代码使用同步执行模式在现有数据库文件中创建一个名为“emp”的表
importmx.controls.Alert;
privatevarcon:
SQLConnection;
privatevarcreateStmt:
SQLStatement;
privatefunctioninitApp():
void
{
varfile:
File=File.applicationStorageDirectory.resolvePath("myTestdb.db")
con=newSQLConnection();
createStmt=newSQLStatement();
try
{
con.open(file);
createStmt.sqlConnection=con;
varsql:
String=
"CREATETABLEIFNOTEXISTSemp("+
" empIdINTEGERPRIMARYKEYAUTOINCREMENT,"+
" firstNameTEXT,"+
" lastNameTEXT,"+
" salaryNUMERICCHECK(salary>0)"+
")";
createStmt.text=sql;
createStmt.execute();
Alert.show("成功完成");
}
catch(error:
SQLError)
{
Alert.show(error.message);
Alert.show(error.details);
}
}
代码下载:
(2)(添加,删除,修改以及语句参数)
本章主要总结数据库的插入,删除,修改,以及语句参数的使用
本章提到的同步和异步操作,不明白的可以看上篇文章
0.SQLStatement类介绍
SQLStatement实例用于针对通过SQLConnection实例打开的本地SQL数据库执行SQL语句。
SQLStatement实例通过将SQLConnection实例设置为SQLStatement实例的sqlConnection属性的值来链接到SQLConnection实例。
text属性用要执行的SQL语句的实际文本进行填充。
如有必要,可以使用parameters属性指定SQL语句参数的值,并通过调用execute()方法执行该语句。
1.插入数据
同步版本:
importmx.controls.Alert;
privatevarcon:
SQLConnection;
privatefunctioninitApp():
void
{
varfile:
File=File.applicationStorageDirectory.resolvePath("myTestdb.db")
con=newSQLConnection();
varstmt:
SQLStatement=newSQLStatement();
try
{
con.open(file);
stmt.sqlConnection=con;
stmt.text="INSERTINTOemp(firstName,lastName,salary)VALUES('f','l',88)";
stmt.execute();
}
catch(error:
SQLError)
{
Alert.show(error.message);
Alert.show(error.details);
}
}
代码说明:
SQLStatement类的实例用于针对通过SQLConnection实例打开的本地SQL数据库执行SQL语句
2.得到已插入行的数据库生成的行标识
得到自动增长列的行标识数值
varstmt:
SQLStatement=newSQLStatement();
stmt.sqlConnection=con;
stmt.text="INSERTINTOemp(firstName,lastName,salary)VALUES('f','l',88)";
stmt.execute();
varresult:
SQLResult=stmt.getResult();
varprimaryKey:
Number=result.lastInsertRowID;
Alert.show(primaryKey.toString());
代码说明:
SQLResult类提供对为响应SQL语句(SQLStatement实例)执行而返回的数据的访问
lastInsertRowID属性:
上次生成的行标识符(由SQLINSERT语句生成),如果执行的语句不是INSERT语句,则该值为0。
3.语句参数的使用
在多次使用一个SQL语句但该语句中的值不同的情况下,最佳方法是使用包括参数的SQL语句而不是在SQL文本中包括字面值。
参数是语句文本中的一个占位符,每次执行语句时都将它替换为实际的值。
参数名称由“:
”或“@”字符后跟一个名称组成,例如:
:
itemName @firstName
还可以使用未命名参数,使用“?
”字符表示SQL语句中的参数。
按照参数在语句中的顺序,每个参数都分配有一个数字索引,数字索引从索引0(表示第一个参数)开始。
使用参数的优点:
1.性能更佳
2.显式数据类型指定
3.安全性更高
实例代码:
得到自动增长列的行标识数值(异步版本)
privatevarstmt1:
SQLStatement;
privatefunctionGetlastInsertRowID():
void
{
stmt1=newSQLStatement();
stmt1.sqlConnection=con;
stmt1.text="INSERTINTOemp(firstName,lastName,salary)VALUES(@firstName,@lastName,@salary)";
stmt1.parameters["@firstName"]="f";
stmt1.parameters["@lastName"]="l";
stmt1.parameters["@salary"]=88;
stmt1.addEventListener(SQLEvent.RESULT,okHandler);
stmt1.addEventListener(SQLErrorEvent.ERROR,errorHandler);
stmt1.execute();
}
privatefunctionokHandler(evt:
SQLEvent):
void
{
Alert.show("插入成功");
varre:
SQLResult=this.stmt1.getResult();
varid:
Number=re.lastInsertRowID;
Alert.show(id.toString());
}
privatefunctionerrorHandler(evt:
SQLErrorEvent):
void
{
Alert.show("失败");
Alert.show(evt.error.message);
Alert.show(evt.error.details);
}
代码说明:
此例题中用到了语句参数@firstName,@lastName,@salary,并分别赋值
要是使用未命名参数,把代码修改如下即可(注意数字索引从0开始):
stmt1.text="INSERTINTOemp(firstName,lastName,salary)VALUES(?
?
?
)";
stmt1.parameters[0]="f";
stmt1.parameters[1]="l";
stmt1.parameters[2]=88;
4.删除操作
privatefunctiondel():
void
{
varstmt:
SQLStatement=newSQLStatement();
stmt.sqlConnection=con;
stmt.text="deletefromempwheresalary=:
salary";
stmt.parameters[":
salary"]=88;
stmt.execute();
varresult:
SQLResult=stmt.getResult();
varcount:
Number=result.rowsAffected;
Alert.show("成功删除"+count.toString()+"行");
}
代码说明:
rowsAffected属性:
指示受此操作影响的行数
请注意,当相关的SQL操作为不带WHERE子句的DELETE语句时(即该语句删除表中的所有行),rowsAffected属性始终为0,而不管删除了多少行。
如果您需要知道删除的行数,则可以包括WHERE子句WHERE1=1,在这种情况下,将删除所有行,并且rowsAffected属性会精确反映已删除的行数
5.修改操作
privatefunctionupdateData():
void
{
varstmt:
SQLStatement=newSQLStatement();
stmt.sqlConnection=con;
stmt.text="updateempsetlastName=:
lastNamewheresalary=:
salary";
stmt.parameters["