日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

swift下FMDB的使用

發(fā)布時(shí)間:2023/12/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 swift下FMDB的使用 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

swift下FMDB的使用
在IOS中可以使用的存儲(chǔ)結(jié)構(gòu)有很多,可以使用文件進(jìn)行緩存,可以使用useDefault實(shí)現(xiàn)簡(jiǎn)單狀態(tài)的存儲(chǔ),此外IOS下有一個(gè)常用的數(shù)據(jù)庫(kù)框架–FMDB,它是對(duì)于SQLite的一層封裝,可以使用它完成基本的增刪查改,也可以對(duì)此完成事務(wù),回滾等復(fù)雜操作
對(duì)于FMDB的集成,我們可以直接使用cocoapod完成集成,就像如下的podfile

target 'YouKu' dopod 'FMDB' end

之后,就可以進(jìn)行操作了,但是由于我使用的是swift,FMDB是使用OC語(yǔ)言封裝的庫(kù),要使用的話(huà),就應(yīng)該在項(xiàng)目的根目錄下面創(chuàng)建一個(gè)bridge.h,在其中導(dǎo)入我們的FMDB
加完以后,我們還需要再info.plist中,進(jìn)行設(shè)置,使得我們的改動(dòng)內(nèi)容生效,點(diǎn)擊項(xiàng)目–TARGETS–Build Settings,其中有一個(gè)設(shè)置是swift compiler - General設(shè)置其中OC橋接文件為之前自定義的文件
之后的話(huà),就可以直接使用了,我們可以先定義一個(gè)公共的操作類(lèi),封裝數(shù)據(jù)的初始化和增刪查改等操作
先定義好我們的實(shí)體類(lèi)對(duì)象

import UIKitclass PersonEntity: NSObject {var id : Int?;var name : String?;var age : Int?;func initParam(id : Int, name : String, age : Int) {self.id = id;self.name = name;self.age = age;}func toString() {print("用戶(hù)信息:id = \(id ?? 0) 姓名 = \(name ?? "") 年齡 = \(age ?? -1)");} }

首先來(lái)說(shuō),這個(gè)類(lèi)應(yīng)該是全局的單例對(duì)象,所以說(shuō),先設(shè)置一個(gè)static的對(duì)象,讓其他的類(lèi)調(diào)用來(lái)獲取到對(duì)象,之后,在使用的時(shí)候要先打開(kāi)db對(duì)象,這里需要注意的問(wèn)題就是,對(duì)于這個(gè)數(shù)據(jù)庫(kù),我們是通過(guò)一個(gè)文件路徑來(lái)生成的,如果原先就存在這個(gè)數(shù)據(jù)庫(kù),會(huì)直接打開(kāi)這個(gè)文件,如果不存在,就會(huì)先創(chuàng)建數(shù)據(jù)庫(kù),在進(jìn)行開(kāi)啟數(shù)據(jù)庫(kù)的操作,值得注意的是,在FMDB中,使用數(shù)據(jù)庫(kù)以后要及時(shí)關(guān)閉數(shù)據(jù)庫(kù),所以來(lái)說(shuō)open和close一般是成對(duì)出現(xiàn)的

import UIKitclass FMDBManager: NSObject {static let shared = FMDBManager();var dbUrl : String?;var FMDBEntity : FMDatabase?;var FMDBQueue : FMDatabaseQueue?;//打開(kāi)數(shù)據(jù)庫(kù),也就是創(chuàng)建數(shù)據(jù)庫(kù)func opendb(dbName : String, tableName : String) {//在doc文件夾下面創(chuàng)建新的文件夾,用來(lái)儲(chǔ)存數(shù)據(jù)庫(kù)let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true);let docPath = paths[0] + "/\(dbName)";self.dbUrl = docPath;//創(chuàng)建新的數(shù)據(jù)庫(kù)self.FMDBEntity = FMDatabase.init(path: self.dbUrl);//如果數(shù)據(jù)庫(kù)存在,就直接打開(kāi),如果不存在,則會(huì)現(xiàn)在磁盤(pán)上創(chuàng)建數(shù)據(jù)庫(kù),然后再打開(kāi)if self.FMDBEntity!.open() {print("數(shù)據(jù)庫(kù)打開(kāi)成功");//創(chuàng)建數(shù)據(jù)表self.initTable(t_name: tableName);}else {print("數(shù)據(jù)庫(kù)打開(kāi)失敗");}//數(shù)據(jù)庫(kù)每次操作完成以后就應(yīng)該釋放資源self.FMDBEntity!.close();}func initTable(t_name : String) {let sql = "CREATE TABLE IF NOT EXISTS \(t_name)( \n" +"id INTEGER PRIMARY KEY AUTOINCREMENT, \n" +"name TEXT, \n" +"age INTEGER \n" +"); \n"if self.FMDBEntity!.executeUpdate(sql, withArgumentsIn: []) {print("數(shù)據(jù)表創(chuàng)建成功");}else {print("數(shù)據(jù)表創(chuàng)建失敗");}}}

這樣的話(huà),我們就完成了數(shù)據(jù)表的創(chuàng)建,如果要進(jìn)行增刪查改,我們就可以借助于FMDatabase執(zhí)行對(duì)應(yīng)的sql代碼,對(duì)于FMDB來(lái)說(shuō),它和一般的數(shù)據(jù)庫(kù)沒(méi)有區(qū)別,所以說(shuō),原先使用的sql基本上沒(méi)有變化,下面舉個(gè)例子,如果我們要增加一條記錄,那么需要執(zhí)行的sql是

insert into table_name (cloum1, cloum2, cloum3...) values(value1, value2, value3...)

接下來(lái),我們就可以編寫(xiě)一個(gè)方法來(lái)執(zhí)行我們的sql,一般來(lái)說(shuō)有兩種方式

  • 使用完整sql
  • 使用占位符,后期填充參數(shù)
    在這里,可以直接把參數(shù)嵌入到自定義的String中,拼接成完整的sql語(yǔ)句用來(lái)執(zhí)行,也可以使用?作為占位符,我使用的是占位符的方式,方法如下
  • func insert(tableName : String, param : [String : AnyObject]) {//定義增加的sqllet sql = "insert into \(tableName) (name, age) values(?, ?)";//開(kāi)啟數(shù)據(jù)庫(kù)連接,執(zhí)行sql語(yǔ)句if self.FMDBEntity!.open() {//數(shù)據(jù)庫(kù)連接已打開(kāi),傳入sql和參數(shù)if self.FMDBEntity!.executeUpdate(sql, withArgumentsIn: ["殷素素", 23]) {print("操作完成");}else{print("操作失敗");}}self.FMDBEntity!.close();}

    而如果要進(jìn)行查詢(xún)操作時(shí),我們就會(huì)接觸到另外一個(gè)對(duì)象,那就是FMDB中的結(jié)果集FMResultSet,這個(gè)東西和jdbc中的結(jié)果集是相通的,可以進(jìn)行逐行的遍歷,得到每條數(shù)據(jù),然后就可以進(jìn)行相應(yīng)的解析,在組合成一個(gè)完整的對(duì)象,也就是下面的方法

    func select(tableName : String, param : [String : AnyObject]) -> [PersonEntity] {let pId = param["id"];//定義增加的sqllet sql = "select * from \(tableName) where id = ?";//開(kāi)啟數(shù)據(jù)庫(kù)連接,執(zhí)行sql語(yǔ)句var persons : [PersonEntity] = [];if self.FMDBEntity!.open() {//數(shù)據(jù)庫(kù)連接已打開(kāi),傳入sql和參數(shù)if let queryResult = self.FMDBEntity?.executeQuery(sql, withArgumentsIn: [pId ?? 0]) {while queryResult.next() {let id = queryResult.int(forColumn: "id");let name = queryResult.string(forColumn: "name") ?? "";let age = queryResult.int(forColumn: "age");let p = PersonEntity();p.initParam(id: Int(id), name: String(name), age: Int(age));persons.append(p);}}}self.FMDBEntity!.close();return persons;}

    下面還有刪除和修改的代碼,沒(méi)有什么特別之處了,就不再贅述了

    func update(tableName : String, param : [String : AnyObject]) {//定義修改的sqllet sql = "update \(tableName) set name = ? where id = ?";//開(kāi)啟數(shù)據(jù)庫(kù)連接,執(zhí)行sql語(yǔ)句if self.FMDBEntity!.open() {//數(shù)據(jù)庫(kù)連接已打開(kāi),傳入sql和參數(shù)if self.FMDBEntity!.executeUpdate(sql, withArgumentsIn: ["張老道", 1]) {print("操作完成");}else{print("操作失敗");}}self.FMDBEntity!.close();}func delete(tableName : String, param : [String : AnyObject]) {//定義刪除的sqllet sql = "delete from \(tableName) where id = ?";//開(kāi)啟數(shù)據(jù)庫(kù)連接,執(zhí)行sql語(yǔ)句if self.FMDBEntity!.open() {//數(shù)據(jù)庫(kù)連接已打開(kāi),傳入sql和參數(shù)if self.FMDBEntity!.executeUpdate(sql, withArgumentsIn: [1]) {print("操作完成");}else{print("操作失敗");}}self.FMDBEntity!.close();}

    有點(diǎn)意思的這個(gè)數(shù)據(jù)庫(kù)里面的事務(wù)操作,在FMDB中事務(wù)操作依賴(lài)于一個(gè)隊(duì)列來(lái)實(shí)現(xiàn),那就是FMDatabaseQueue,先貼出來(lái)代碼,然后再分析一下,先是隊(duì)列的初始化

    //執(zhí)行之前需要先初始化數(shù)據(jù)庫(kù)func openQueue(dbName : String, tableName : String) {let path = self.dbUrl ?? "";if path == "" {print("要先完成初始化");self.opendb(dbName: dbName, tableName: tableName);}self.FMDBQueue = FMDatabaseQueue.init(path: self.dbUrl);}

    之后執(zhí)行批量執(zhí)行的代碼

    @objc func batchHandle() {print("批量插入");FMDBManager.shared.FMDBQueue?.inTransaction({ (db, rollback) inlet trueTable = "t_Student";let errorTable = "t_Sent";for i in 40..<50{var sql = "insert into \(trueTable) (name, age) values(?, ?)";if i == 45 {sql = "insert into \(errorTable) (name, age) values(?, ?)";}let result : Bool = db.executeUpdate(sql, withArgumentsIn: ["張啟山", i]);if result {print("插入數(shù)據(jù):\(i)");}else{print("出現(xiàn)錯(cuò)誤,開(kāi)始回滾");rollback.pointee = true;return ;}}})}

    所以來(lái)說(shuō),進(jìn)行批量查詢(xún)的代碼關(guān)鍵就在inTransaction這個(gè)方法中,如果直接點(diǎn)進(jìn)去,我們會(huì)到達(dá)源代碼中的這個(gè)位置

    直接往里跳,會(huì)到具體的代碼實(shí)現(xiàn)

    - (void)beginTransaction:(FMDBTransaction)transaction withBlock:(void (^)(FMDatabase *db, BOOL *rollback))block {FMDBRetain(self);dispatch_sync(_queue, ^() { BOOL shouldRollback = NO;switch (transaction) {case FMDBTransactionExclusive:[[self database] beginTransaction];break;case FMDBTransactionDeferred:[[self database] beginDeferredTransaction];break;case FMDBTransactionImmediate:[[self database] beginImmediateTransaction];break;}block([self database], &shouldRollback);if (shouldRollback) {[[self database] rollback];}else {[[self database] commit];}});FMDBRelease(self); }//下面這兩段源代碼是FMDatabase.m文件里面的函數(shù) - (BOOL)rollback {BOOL b = [self executeUpdate:@"rollback transaction"];if (b) {_isInTransaction = NO;}return b; }- (BOOL)commit {BOOL b = [self executeUpdate:@"commit transaction"];if (b) {_isInTransaction = NO;}return b; }

    不難看出,接下來(lái),我們會(huì)跳轉(zhuǎn)到beginTransaction方法,那這個(gè)方法執(zhí)行內(nèi)容又是什么呢,其實(shí)就只有一行代碼

    - (BOOL)beginTransaction {BOOL b = [self executeUpdate:@"begin exclusive transaction"];if (b) {_isInTransaction = YES;}return b; }

    就是執(zhí)行了begin exclusive transaction,然后由于我們實(shí)現(xiàn)了源代碼里面的block,會(huì)在這條執(zhí)行以后粘貼上十條sql,然后根據(jù)shouldRollback的值決定最后的代碼,我們?cè)谧约旱拇a執(zhí)行時(shí),通過(guò)判斷每一插入語(yǔ)句的執(zhí)行結(jié)果,決定返回的布爾值,然后如果每條代碼都能執(zhí)行,就提交commit,所有代碼提交生效,否則就提交rollback,所有代碼回滾,完成了事務(wù)的功能
    參考文章
    第一篇文章
    第二篇文章
    第三篇文章
    對(duì)于更多的FMDB和Model封裝操作,可以參考下面這篇文章,所的也很豐富,有興趣的可以自己研究一下
    實(shí)體類(lèi)與數(shù)據(jù)庫(kù)表的關(guān)聯(lián)映射

    總結(jié)

    以上是生活随笔為你收集整理的swift下FMDB的使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。