[iOS]數(shù)據(jù)庫第三方框架FMDB詳細(xì)講解

初識FMDB

iOS中原生的SQLiteAPI在進(jìn)行數(shù)據(jù)存儲的時候缤骨,需要使用C語言中的函數(shù)爱咬,操作比較麻煩。于是绊起,就出現(xiàn)了一系列將SQLite API進(jìn)行封裝的庫精拟,例如FMDB、PlausibleDatabase虱歪、sqlitepersistentobjects等蜂绎。

FMDB是一款簡潔、易用的封裝庫笋鄙。因此师枣,在這里推薦使用第三方框架FMDB,它是對libsqlite3框架的封裝萧落,用起來的步驟與SQLite使用類似践美,并且它對于多線程的并發(fā)操作進(jìn)行了處理劳殖,所以是線程安全的。

FMDB PK Sqlite

優(yōu)點(diǎn):

對多線程的并發(fā)操作進(jìn)行處理拨脉,所以是線程安全的哆姻;

以O(shè)C的方式封裝了SQLite的C語言API,使用起來更加的方便玫膀;

FMDB是輕量級的框架矛缨,使用靈活。

缺點(diǎn):

因為它是OC的語言封裝的帖旨,只能在ios開發(fā)的時候使用箕昭,所以在實(shí)現(xiàn)跨平臺操作的時候存在局限性。

FMDB框架中重要的框架類

FMDatabase

FMDatabase對象就代表一個單獨(dú)的SQLite數(shù)據(jù)庫解阅,用來執(zhí)行SQL語句

FMResultSet

使用FMDatabase執(zhí)行查詢后的結(jié)果集

FMDatabaseQueue

用于在多線程中執(zhí)行多個查詢或更新落竹,它是線程安全的

FMDB使用步驟

下載FMDB文件GitHub,并將FMDB文件夾添加到項目中(也可使用CocoaPods導(dǎo)入)

導(dǎo)入libsqlite3.0框架,導(dǎo)入頭文件FMDatabase.h

代碼實(shí)現(xiàn)货抄,與SQLite使用步驟相似述召,創(chuàng)建數(shù)據(jù)庫路徑,獲得數(shù)據(jù)庫路徑蟹地,打開數(shù)據(jù)庫积暖,然后對數(shù)據(jù)庫進(jìn)行增、刪怪与、改夺刑、查操作,最后關(guān)閉數(shù)據(jù)庫分别。

step.png

數(shù)據(jù)庫創(chuàng)建

創(chuàng)建FMDatabase對象時參數(shù)為SQLite數(shù)據(jù)庫文件路徑遍愿,該路徑可以是以下三種方式之一

文件路徑。該文件路徑無需真實(shí)存在耘斩,如果不存在會自動創(chuàng)建

空字符串(@“”)沼填。表示會在臨時目錄創(chuàng)建一個空的數(shù)據(jù)庫,當(dāng)FMDatabase連接關(guān)閉時煌往,文件也會被刪除

NULL倾哺。將創(chuàng)建一個內(nèi)在數(shù)據(jù)庫,同樣的刽脖,當(dāng)FMDatabase連接關(guān)閉時,數(shù)據(jù)將會被銷毀

本文中使用的測試模型類.h

student.png

數(shù)據(jù)庫使用FMDB框架代碼操作

使用FMDataBase類建立數(shù)據(jù)庫

//1.獲得數(shù)據(jù)庫文件的路徑

NSString*doc =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)? lastObject];

NSString*fileName = [doc stringByAppendingPathComponent:@“student.sqlite”];

//2.獲得數(shù)據(jù)庫

FMDatabase *db = [FMDatabase databaseWithPath:fileName];

//3.使用如下語句忌愚,如果打開失敗曲管,可能是權(quán)限不足或者資源不足。通常打開完操作操作后硕糊,需要調(diào)用 close 方法來關(guān)閉數(shù)據(jù)庫院水。在和數(shù)據(jù)庫交互 之前腊徙,數(shù)據(jù)庫必須是打開的。如果資源或權(quán)限不足無法打開或創(chuàng)建數(shù)據(jù)庫檬某,都會導(dǎo)致打開失敗撬腾。

if([db open])

{

//4.創(chuàng)表

BOOLresult = [db executeUpdate:@“CREATE TABLE IF NOT EXISTS t_student (idinteger PRIMARY KEY AUTOINCREM ENT, name text NOTNULL, age integer NOTNULL);”];

if(result)

{

NSLog(@“創(chuàng)建表成功”);

}

}

查看sql表

根據(jù)路徑fileName在Finder中搜索.sqlite文件,并復(fù)制到桌面

使用火狐瀏覽器工具下的SQLite Manager打開.sqlite文件

2.png

數(shù)據(jù)表結(jié)構(gòu)

sql.png

使用FMDataBase類執(zhí)行數(shù)據(jù)庫命令SQL

一切不是SELECT命令的命令都視為更新恢恼。這包括 CREAT,UPDATE,INSERT,ALTER,BEGIN,COMMIT,DETACH,DELETE,DROP,END,EXPLAIN,VACUUM,REPLACE等民傻。

簡單來說,只要不是以SELECT開頭的命令都是更新命令场斑。

執(zhí)行更新返回一個BOOL值漓踢。YES表示 執(zhí)行成功,否則表示有錯誤漏隐。你可以調(diào)用 -lastErrorMessage 和 -lastErrorCode方法來得到更多信息喧半。

使用FMDataBase類執(zhí)行數(shù)據(jù)庫插入命令SQLinsert into

int age = 42;

//1.executeUpdate:不確定的參數(shù)用?來占位(后面參數(shù)必須是oc對象青责,挺据;代表語句結(jié)束)

[self.db executeUpdate:@“INSERTINTOt_student (name, age)VALUES(?,?);”,name,@(age)];

//2.executeUpdateWithForamat:不確定的參數(shù)用%@,%d等來占位 (參數(shù)為原始數(shù)據(jù)類型脖隶,執(zhí)行語句不區(qū)分大小寫)

[self.db executeUpdateWithForamat:@“insertintot_student (name,age)values(%@,%i);”,name,age];

//3.參數(shù)是數(shù)組的使用方式

[self.db executeUpdate:@“INSERTINTO

t_student(name,age)VALUES(?,?);”withArgumentsInArray:@[name,@(age????????????? )]];

使用FMDataBase類執(zhí)行數(shù)據(jù)庫刪除命令SQLdelete

//1.不確定的參數(shù)用吴菠?來占位 (后面參數(shù)必須是oc對象,需要將int包裝成OC對象)

intidNum =101;

[self.db executeUpdate:@“deletefrom t_student where id = ?;”,@(idNum)];

//2.不確定的參數(shù)用%@,%d等來占位

[self.db executeUpdateWithFormat:@“deletefrom t_student where name = %@;”,@“apple_name”];

使用FMDataBase類執(zhí)行數(shù)據(jù)庫修改命令SQLupdate

//修改學(xué)生的名字

[self.db executeUpdate:@“updatet_studentsetname= ?wherename= ?”,newName,oldName];

使用FMDataBase類執(zhí)行數(shù)據(jù)庫查詢命令SQLselect ... from

SELECT命令就是查詢浩村,執(zhí)行查詢的方法是以-excuteQuery開頭的做葵。

執(zhí)行查詢時,如果成功返回FMResultSet對象心墅,錯誤返回nil酿矢。與執(zhí)行更新相當(dāng),支持使用NSError參數(shù)怎燥。

同時瘫筐,你也可以使用-lastErrorCode和-lastErrorMessage獲知錯誤信息。

FMResultSet獲取不同數(shù)據(jù)格式的方法

intForColumn:

longForColumn:

longLongIntForColumn:

boolForColumn:

doubleForColumn:

stringForColumn:

dataForColumn:

dataNoCopyForColumn:

UTF8StringForColumnIndex:

objectForColumn:

使用FMResultSet獲取查詢語句結(jié)果

//查詢整個表

FMResultSet *resultSet = [self.db execute Query:@“select* from t_student;”];

//根據(jù)條件查詢

FMResultSet *resultSet = [self.db executeQuery:@“select* from t_student where id

//遍歷結(jié)果集合

while([resultSet? next])

{

intidNum = [resultSet intForColumn:@“id”]铐姚;

NSString *name = [resultSet

objectForColumn:@“name”];

intage = [resultSet intForColumn:@“age”];

}

使用FMDataBase類執(zhí)行數(shù)據(jù)庫銷毀命令SQLdrop ...

//如果表格存在 則銷毀

[self.db executeUpadate:@“droptableifexistst_student;”];

使用FMDatabaseQueue類實(shí)現(xiàn)多線程操作

在多個線程中同時使用一個FMDatabase實(shí)例是不明智的〔吒危現(xiàn)在你可以為每 個線程創(chuàng)建一個FMDatabase對象,不要讓多個線程分享同一個實(shí)例隐绵,他無 法在多個線程中同事使用之众。否則程序會時不時崩潰或者報告異常。所以依许,不要 初始化FMDatabase對象棺禾,然后在多個線程中使用。這時候峭跳,我們就需要使 用FMDatabaseQueue來創(chuàng)建隊列執(zhí)行事務(wù)膘婶。

//1.創(chuàng)建隊列

FMDatabaseQueue *queue = [FMDatabaseQueue

databaseQueueWithPath:aPath];

__block BOOL whoopsSomethingWrongHappened =true;

//2.把任務(wù)包裝到事務(wù)里

[queueinTransaction:^(FMDatabase *db, BOOL *rollback)

{

whoopsSomethingWrongHappened &=? [dbexecuteUpdate:@“INSERT INTO myTable VALUES (?)”,???? [NSNumber numberWith:1]];

whoopsSomethingWrongHappened &= [db

executeUpdata:@“INSERT INTO myTable VALUES (?)”,

[NSNumber numberWithInt:2]];

whoopsSomethingWrongHappened &= [db

executeUpdata:@“INSERT INTO myTable VALUES (?)”[NSNumber

numberWithInt:3]];

//如果有錯誤 返回

if(!whoopsSomethingWrongHappened)

{

*rollback = YES;

return;

}

}];

自己測試:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末缺前,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子悬襟,更是在濱河造成了極大的恐慌衅码,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脊岳,死亡現(xiàn)場離奇詭異逝段,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)逸绎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門惹恃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人棺牧,你說我怎么就攤上這事巫糙。” “怎么了颊乘?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵参淹,是天一觀的道長。 經(jīng)常有香客問我乏悄,道長浙值,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任檩小,我火速辦了婚禮开呐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘规求。我一直安慰自己筐付,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布阻肿。 她就那樣靜靜地躺著瓦戚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪丛塌。 梳的紋絲不亂的頭發(fā)上较解,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機(jī)與錄音赴邻,去河邊找鬼印衔。 笑死,一個胖子當(dāng)著我的面吹牛乍楚,可吹牛的內(nèi)容都是我干的当编。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼徒溪,長吁一口氣:“原來是場噩夢啊……” “哼忿偷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起臊泌,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤鲤桥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后渠概,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體茶凳,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年播揪,在試婚紗的時候發(fā)現(xiàn)自己被綠了贮喧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡猪狈,死狀恐怖箱沦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情雇庙,我是刑警寧澤谓形,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站疆前,受9級特大地震影響寒跳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜竹椒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一童太、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胸完,春花似錦书释、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至誓琼,卻和暖如春检激,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背腹侣。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工叔收, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人傲隶。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓饺律,卻偏偏與公主長得像,于是被迫代替她去往敵國和親跺株。 傳聞我的和親對象是個殘疾皇子复濒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容