西湖区外贸网站建设,seo属于运营还是技术,wordpress 关闭边栏,wordpress排版Markdown前言在我们的日常开发中#xff0c;经常会遇到用户断网或者网络较慢的情况#xff0c;这样用户在一进入页面的时候会显示空白的页面#xff0c;那么如何避免没网显示空白页面的尴尬呢#xff1f;答案就是#xff1a;先在网络好的时候缓存一部分数据#xff0c;这样当下次…前言在我们的日常开发中经常会遇到用户断网或者网络较慢的情况这样用户在一进入页面的时候会显示空白的页面那么如何避免没网显示空白页面的尴尬呢答案就是先在网络好的时候缓存一部分数据这样当下次网络情况不好的时候至少用户可以先看到之前缓存的内容已达到提高APP的用户体验。SQLite就是我们实现本地数据缓存的一种方案SQLite有以下优点iOS内嵌SQLite经过时间的验证开源跨平台。OK废话不多说现在我们就开始进入SQLite的体验之旅。当然在开始之前我们要做一点准备工作毕竟我们不打没有准备的仗。准备工作创建备用数据导入SQLite3:import SQLite3创建一个Goods的类用来表示数据库存储的数据类型创建一个Goods类型的数组声明一个dbPath和db的全局变量声明一个获取libraryDirectory路径的函数(数据库存放路径如何选择)代码如下class Goods {let name: String!let weight: Int!var price: Double!init(name: String, weight: Int, price: Double) {self.name nameself.weight weightself.price price}}let goods Goods(name: computer, weight: 10, price: 2000.0)var goodArr [Goods]()var dbPath var db: OpaquePointer?func createData() {for index in 0...4 {let goods Goods(name: computer \(index), weight: index * 10, price: 20.0)goodArr.append(goods)}}func fetchLibraryPath() {if let libraryPathString NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).first {let pathURL URL(fileURLWithPath: libraryPathString).appendingPathComponent(goods.sqlite)dbPath pathURL.path}}创建并连接数据库func openDatabase() - OpaquePointer? {var db: OpaquePointer?if sqlite3_open(dbPath, db) SQLITE_OK {resultLabel.text 成功打开数据库路径\(dbPath)return db} else {resultLabel.text 打开数据库失败return nil}}通过上面的代码我们可以看到首先声明了一个OpaquePointer类型的可选值db接下来调用了sqlite3_open()方法该方法的作用是如果之前创建了数据库那么直接打开若没创建会直接创建一个。如果该方法调用成功他会返回一个OpaquePointer的值赋值给你传递进去的db。SQLITE_OK是一个定义在SQLite库中的一个常量它代表一个Int32的0。SQLite的大多数函数都会返回一个Int32的值例如SQLITE_ROW (100)、SQLITE_DONE (101)等详细列表你可以查看这里。现在你可以通过调用db openDatabase()来打开或者创建一个数据库了正常情况下你会看见成功打开数据库路径xxx/xxx.sqlite的输出。现在我们已经成功的创建了一个名字为goods.sqlite的数据库了接下来我们要做的就是创建一个表了。创建表代码func createTable() {let createTableString CREATE TABLE Computer(Id INT PRIMARY KEY NOT NULL,Name CHAR(255),Weight Int,Price Float);var createTableStatement: OpaquePointer?// 第一步if sqlite3_prepare_v2(db, createTableString, -1, createTableStatement, nil) SQLITE_OK {// 第二步if sqlite3_step(createTableStatement) SQLITE_DONE {resultLabel.text 成功创建表} else {resultLabel.text 未成功创建表}} else {}//第三步sqlite3_finalize(createTableStatement)}代码说明首先解释一下createTableString:创建一个名字为Computer的表Id为主键且不为空Name不超过255个字符Weight为Int类型Price为Float类型。然后创建了一个OpaquePointer?类型的变量用于下面的函数sqlite3_prepare_v2()。第一步该函数会将createTableString编译为字节代码(byte code)并返回一个status code这个函数执行成功则表明database已经准备好了执行任意的SQL statement(就是创建的SQL的字符串)该函数执行成功后即会执行sqlite3_step()。第二步sqlite3_step()用来执行编译完成的statement handle(createTableStatement)并返回一个status code。第三步在你每一次的操作完成后你必须调用sqlite3_finalize()去删除你的statement以避免resource leak。注意一旦一个statement被finalized你不应该再一次使用它。插入一条数据代码func insertOneData() {let insertRowString INSERT INTO Computer (Id, Name, Weight, Price) VALUES (?, ?, ?, ?);var insertStatement: OpaquePointer?//第一步if sqlite3_prepare_v2(db, insertRowString, -1, insertStatement, nil) SQLITE_OK {let id: Int32 1//第二步sqlite3_bind_int(insertStatement, 1, id)sqlite3_bind_text(insertStatement, 2, goods.name, -1, nil)sqlite3_bind_int(insertStatement, 3, Int32(goods.weight))sqlite3_bind_double(insertStatement, 4, goods.price)//第三步if sqlite3_step(insertStatement) SQLITE_DONE {resultLabel.text 插入数据成功} else {resultLabel.text 插入数据失败}} else {}//第四步sqlite3_finalize(insertStatement)}代码说明insertRowString中的?和前面的字段是对应的它只是占位符的意思告诉编译器当真正执行该语句的时候会插入相应的值。第二步sqlite3_bind_int()标识你绑定了一个Int类型的值该函数的第一个参数是你的statement(即insertStatement)第二个参数是?的位置在你的statement(注意该值是非零的)在此处也就是1第三个参数为你想绑定的值。sqlite3_bind_text()函数表示你绑定的是一个text(一般用于比较长的字符串)类型值该函数比sqlite3_bind_int()多了额外的两个参数第四个参数的意思是text的字节数一般穿-1,第五个参数是一个closure回调处理完string后调用。第三步第四步同上插入多条数据代码func insertMutipleData() {let insertRowString INSERT INTO Computer (Id, Name, Weight, Price) VALUES (?, ?, ?, ?);var insertStatement: OpaquePointer?//第一步if sqlite3_prepare_v2(db, insertRowString, -1, insertStatement, nil) SQLITE_OK {for (index, good) in goodArr.enumerated() {let id: Int32 Int32(index 1)//第二步sqlite3_bind_int(insertStatement, 1, id)sqlite3_bind_text(insertStatement, 2, good.name, -1, nil)sqlite3_bind_int(insertStatement, 3, Int32(good.weight))sqlite3_bind_double(insertStatement, 4, good.price)//第三步if sqlite3_step(insertStatement) SQLITE_DONE {resultLabel.text 插入数据成功} else {resultLabel.text 插入数据失败}//第四步sqlite3_reset(insertStatement)}} else {}//第五步sqlite3_finalize(insertStatement)}代码说明insertRowString同上。第四步调用sqlite3_reset()函数以便下次循环再次执行insertStatement第一步、第二步、第三步、第五步同上。更新数据代码func updateData() {let updateString UPDATE Computer SET Name changeComputer WHERE Id 2;var updateStatement: OpaquePointer?//第一步if sqlite3_prepare_v2(db, updateString, -1, updateStatement, nil) SQLITE_OK {//第二步if sqlite3_step(updateStatement) SQLITE_DONE {resultLabel.text 更新成功} else {}}//第三步sqlite3_finalize(updateStatement)}代码说明updateString将Id2的数据的Name字段改为changeComputer。sqlite3_prepare_v2()准备sqlite3_step()执行更新statementsqlite3_finalize()结束。删除数据代码func deleteData() {let deleteString DELETE FROM Computer WHERE Id 2;var deleteStatement: OpaquePointer?//第一步if sqlite3_prepare_v2(db, deleteString, -1, deleteStatement, nil) SQLITE_OK {//第二步if sqlite3_step(deleteStatement) SQLITE_DONE {resultLabel.text 删除成功}} else {}//第三步sqlite3_finalize(deleteStatement)}代码说明deleteString删除表中Id2的数据。sqlite3_prepare_v2()准备sqlite3_step()执行删除statementsqlite3_finalize()结束。查询一条数据代码func queryOneData() {let queryString SELECT * FROM Computer WHERE Id 2;var queryStatement: OpaquePointer?//第一步if sqlite3_prepare_v2(db, queryString, -1, queryStatement, nil) SQLITE_OK {//第二步if sqlite3_step(queryStatement) SQLITE_ROW {//第三步let id sqlite3_column_int(queryStatement, 0)let queryResultName sqlite3_column_text(queryStatement, 1)let name String(cString: queryResultName!)let weight sqlite3_column_int(queryStatement, 2)let price sqlite3_column_double(queryStatement, 3)resultLabel.text id: \(id), name: \(name), weight: \(weight), price: \(price)} else {resultLabel.text error}}//第四步sqlite3_finalize(queryStatement)}代码说明queryString在Computer表中查找所有Id 2的数据。第二步注意此时要判断的status code为SQLITE_ROW如果该判断为true则代表你查询的数据存在在表里。第三步sqlite3_column_int()函数是按照列数取数据第一个参数是statement第二个参数则是该字段是第几列(Id 为表里的第一列从0开始计算)。sqlite3_column_text()要略微复杂一点他需要转换类型通过String(cString: queryResultName!)。第一步、第四步同上查询多条数据代码func queryAllData() {let queryString SELECT * FROM Computer;var queryStatement: OpaquePointer?//第一步if sqlite3_prepare_v2(db, queryString, -1, queryStatement, nil) SQLITE_OK {//第二步while(sqlite3_step(queryStatement) SQLITE_ROW) {//第三步let id sqlite3_column_int(queryStatement, 0)let queryResultName sqlite3_column_text(queryStatement, 1)let name String(cString: queryResultName!)let weight sqlite3_column_int(queryStatement, 2)let price sqlite3_column_double(queryStatement, 3)resultLabel.text id: \(id), name: \(name), weight: \(weight), price: \(price)}}//第四步sqlite3_finalize(queryStatement)}代码说明第二步此处为while循环当查询到最后一行时会返回SQLITE_DONE状态码来结束。第一步第三步第四步同上。小结通过上面我们可以总结出执行一个statement的大概流程:sqlite3_prepare_v2()准备sqlite3_step()执行statementsqlite3_finalize()结束。好了到这里SQLite3的增删改查基本操作也就完事了。下一篇我们来了解一下SQLite的进阶用法。Bye~好了以上就是这篇文章的全部内容了希望本文的内容对大家的学习或者工作具有一定的参考学习价值谢谢大家对脚本之家的支持。