[tr][td]本篇没有考虑异步,多线程及SQL注入
WebDatabase 规范中说这份规范不再维护了,原因是同质化(几乎实现者都选择了Sqlite), 且不说这些,单看在HTML5中如何实现离线数据的CRUD,最基本的用法(入门级别) 1,打开数据库 2,创建表 3,新增数据 4,更新数据 5,读取数据 6,删除数据 事实上,关键点在于如何拿到一个可执行SQL语句的上下文, 像创建表,删除表,CRUD操作等仅区别于SQL语句的写法.OK,貌似"SqlHelper"啊,换个名字,dataBaseOperator就它了 executeReader,executeScalar两个方法与executeNonQuery严重同质, 下边的代码产生定义了我们的dataBaseOperator"类",第二行 3-5行则定义打开数据库连接方法,"类方法",效果类似C#中的静态方法,直接类名.方法调用 6-15行则定义executeNonQuery方法,意指查询数据库,与executeReader方法和executeScalar方法同质,均可返回记录集 整个 dataBaseOperator就完整了,很简单,唯一要指出的是,测试以下代码时请选择一个支持HTML5的浏览器!如Google Chrome [list=1] [*]//TODO;SQL注入 [*] function dataBaseOperator() {}; [*] dataBaseOperator.openDatabase = function () { [*] return window.openDatabase("dataBaseUserStories", "1.0", "dataBase used for user stories", 2 * 1024 * 1024); [*] } [*] dataBaseOperator.executeNonQuery = function (sql, parameters, callback) { [*] var db = this.openDatabase(); [*] db.transaction(function (trans) { [*] trans.executeSql(sql, parameters, function (trans, result) { [*] callback(result); [*] }, function (trans, error) { [*] throw error.message; [*] }); [*] }); [*] } [*] dataBaseOperatordataBaseOperator.executeReader = dataBaseOperator.executeNonQuery; [*] dataBaseOperatordataBaseOperator.executeScalar = dataBaseOperator.executeNonQuery; [/list] 有了"SqlHeper",再看业务处理层(Business Logic Layer) 业务处理类包括了创建表,删除表,新增记录,删除记录以及读取记录,这里没有写更新,实际上先删后增一样滴,即使要写也不复杂 [list=1] [*]function userStoryProvider() { [*] this.createUserStoryTable = function () { [*] dataBaseOperator.executeNonQuery("CREATE TABLE tbUserStories(id integer primary key autoincrement,role,ability,benefit,name,importance,estimate,notes)"); [*] }; [*] this.dropUserStoryTable = function () { [*] dataBaseOperator.executeNonQuery("DROP TABLE tbUserStories"); [*] }; [*] this.addUserStory = function (role, ability, benefit, name, importance, estimate, notes) { [*] dataBaseOperator.executeNonQuery("INSERT INTO tbUserStories(role,ability,benefit,name,importance,estimate,notes) SELECT ?,?,?,?,?,?,?", [*] [role, ability, benefit, name, importance, estimate, notes], function (result) { [*] //alert("rowsAffected:" + result.rowsAffected); [*] }); [*] }; [*] this.removeUserStory = function (id) { [*] dataBaseOperator.executeNonQuery("DELETE FROM tbUserStories WHERE id = ?", [id], function (result) { [*] //alert("rowsAffected:" + result.rowsAffected); [*] }); [*] }; [*] this.loadUserStories = function (callback) { [*] dataBaseOperator.executeReader("SELECT * FROM tbUserStories", [], function (result) { [*] callback(result); [*] }); [*] //result.insertId,result.rowsAffected,result.rows24 }; [*] } [/list] createUserStoryTable,dropUserStoryTable,addUserStory,removeUserStory又是严重同质,不说了,仅SQL语句不同而已 但loadUserStories与上述四个方法均不同,是因为它把SQLResultSetRowList返回给了调用者,这里仍然是简单的"转发",页面在使用的时候需要首先创建provider实例(使用类似C#中的类实例上的方法调用) [list=1] [*]var _userStoryProvider = new userStoryProvider(); [/list] 之后就可以调用该实例的方法了,仅举个例子,具体代码省去 [list=1] [*]function loadUserStory() { [*]try { [*]_userStoryProvider.loadUserStories(function (result) { [*] var _userStories = new Array(); [*]for (var i = 0; i delete"; [*] return td; [*] } [*] function removeRow(obj) { [*] document.getElementById("user_story_table").deleteRow(obj.parentNode.parentNode.rowIndex); [*] //obj.parentNode.parentNode.removeNode(true); [*] } [/list] 看完代码复习下基本功课 1,WindowDatabase接口,注意openDatabase方法 [list=1] [*][Supplemental, NoInterfaceObject] [*]interface WindowDatabase { [*] Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in optional DatabaseCallback creationCallback);}; [*]Window implements WindowDatabase; [*][Supplemental, NoInterfaceObject] [*]interface WorkerUtilsDatabase { [*] Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in optional DatabaseCallback creationCallback); DatabaseSync openDatabaseSync(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in optional DatabaseCallback creationCallback);}; [*]WorkerUtils implements WorkerUtilsDatabase; [*][Callback=FunctionOnly, NoInterfaceObject] [*]interface DatabaseCallback { [*]void handleEvent(in Database database); [*]}; [/list] 2,SQLTransaction接口,关注executeSql方法 [list=1] [*]typedef sequence ObjectArray; [*]interface SQLTransaction { [*] void executeSql(in DOMString sqlStatement, in optional ObjectArray arguments, in optional SQLStatementCallback callback, in optional SQLStatementErrorCallback errorCallback);}; [*][Callback=FunctionOnly, NoInterfaceObject] [*]interface SQLStatementCallback { [*] void handleEvent(in SQLTransaction transaction, in SQLResultSet resultSet);}; [*][Callback=FunctionOnly, NoInterfaceObject] [*]interface SQLStatementErrorCallback { [*] boolean handleEvent(in SQLTransaction transaction, in SQLError error); [*]}; [/list] 3,最后看下SQLResultSetRowList定义 [list=1] [*]interface SQLResultSetRowList { [*] readonly attribute unsigned long length; [*]getter any item(in unsigned long index); [*]}; [/list] 和SQLResultSet定义 [list=1] [*]interface SQLResultSet { [*] readonly attribute long insertId; [*] readonly attribute long rowsAffected; [*] readonly attribute SQLResultSetRowList rows; [*] }; [/list][/td][/tr] |
|