iOS FMDB庫詳解

更新時間:2018-11-22 新增了插入/修改數(shù)據(jù)的注意事項(空值問題)
更新時間:2018-11-06 新增了修改(更新)數(shù)據(jù)時的多字段修改
更新時間:2018-07-13 修改了推薦的SQLite可視化工具
更新時間:2017-04-17 修改了代碼的排版

前言(嘮叨)

在網(wǎng)上搜FMDB的資料勤揩,要么是很精簡的介紹(針對比較有經(jīng)驗的開發(fā)者,新手無從下手),要么是排版亂七八糟、代碼有不少錯誤的(直接拷貝過去使用不了,新手還是很難玩轉(zhuǎn))高氮。FMDB作為這么棒的第三方庫,竟然沒有一篇文章是專門系統(tǒng)的、詳細(xì)的介紹它的屡江,簡直不能忍。鄙人尋思著給大家寫一篇赛不,于是就有了這篇“FMDB庫詳解”惩嘉,有錯誤或者不對的地方請大家及時的指正,鄙人將第一時間火速修改踢故,力爭做到文章的代碼拷貝就能用文黎,插上就能用(方便新手和大家的開發(fā)),另外文章中的代碼也力爭做到簡潔高效通俗大師化殿较。本文將持續(xù)更新

什么是FMDB

很簡單耸峭,一個iOS中SQLite API的封裝庫。

其他的巴拉巴拉一大堆總結(jié)下來就是:
1.是對libsqlite3庫的封裝淋纲,使用起來簡潔劳闹、高效,沒有原來的一大堆晦澀難懂、影響開發(fā)效率的C語句本涕,更加面向?qū)ο?br> 2.非常的輕量化业汰、靈活
3.對于多線程的并發(fā)操作進(jìn)行了處理,是線程安全的(重要特性之一)
4.因為它是OC語言封裝的菩颖,只能在ios開發(fā)的時候使用样漆,所以在實現(xiàn)跨平臺操作的時候存在局限性

FMDB重要(常用)類

  • FMDatabase:一個FMDatabase對象就代表一個單獨(dú)的SQLite數(shù)據(jù)庫(注意并不是表),用來執(zhí)行SQL語句
  • FMResultSet:使用FMDatabase執(zhí)行查詢后的結(jié)果集
  • FMDatabaseQueue:用于在多線程中執(zhí)行多個查詢或更新,它是線程安全的

FMDB的使用步驟詳解

1.準(zhǔn)備步驟(基礎(chǔ)操作)

1.項目中導(dǎo)入FMDB Github地址

2.導(dǎo)入libsqlite3框架(一般情況下默認(rèn)是導(dǎo)入的,所以一般都不用做這一步),細(xì)心的朋友可能會發(fā)現(xiàn)我們的庫中還有一個libsqlite3.0框架窿冯,那么它們倆有什么區(qū)別呢

libsqlite3的導(dǎo)入步驟.png

3.在需要用到FMDB的控制器(或模型)地方import FMDatabase.h

FMDB的導(dǎo)入.png

4.新建一個繼承自NSObject的對象骗奖,這里我們使用student,接下來數(shù)據(jù)庫中增刪改查的對象就用stduent進(jìn)行操作示例

student對象.png

5.你已經(jīng)躍躍欲試了吧醒串,別急执桌,本地的.sqlite你現(xiàn)在還無法查看,這里非常推薦火狐瀏覽器中的插件 SQLite Manager 現(xiàn)在推薦App Store里面自帶的Datum Free(免費(fèi)版)了芜赌,使用起來幾乎和火狐插件一毛一樣仰挣。

Mac官方的應(yīng)用商店App Store中的Datum free

(現(xiàn)在已經(jīng)不支持了)火狐瀏覽器插件.png

這里教大家一個快速打開sqlite文件的小技巧,在Finder中將.sqlite文件直接拖動到SQLite Manager的打開文件夾中缠沈,可以自動尋址快速打開


SQLite Manager界面.png
Finder中的.sqlite文件.png
sqlite文件打開后的樣子.png

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

需要用到的全局變量(防止新手不理解代碼)
//1.獲取數(shù)據(jù)庫文件的路徑
_docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSLog(@"%@",_docPath);
mark_student = 1;
//設(shè)置數(shù)據(jù)庫名稱
NSString *fileName = [_docPath stringByAppendingPathComponent:@"student.sqlite"];
//2.獲取數(shù)據(jù)庫
 _db = [FMDatabase databaseWithPath:fileName];
if ([_db open]) {
    NSLog(@"打開數(shù)據(jù)庫成功");
} else {
    NSLog(@"打開數(shù)據(jù)庫失敗");
}

這里我們可以打開_docPath的路徑膘壶,可以看到名為“student.sqlite”的數(shù)據(jù)庫已經(jīng)創(chuàng)建了


student.sqlite

3.表的創(chuàng)建

//3.創(chuàng)建表
BOOL result = [_db executeUpdate:@"CREATE TABLE IF NOT EXISTS t_student (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, age integer NOT NULL, sex text NOT NULL);"];
if (result) {  
  NSLog(@"創(chuàng)建表成功");
} else {
  NSLog(@"創(chuàng)建表失敗");
}

使用火狐瀏覽器的SQLite Manager插件打開student.sqlite可以看到t_student表已經(jīng)被創(chuàng)建

t_student表

4.添加數(shù)據(jù)

//插入數(shù)據(jù)
NSString *name = [NSString stringWithFormat:@"王子涵%@",@(mark_student)];
int age = mark_student;
NSString *sex = @"男";
mark_student ++;
//1.executeUpdate:不確定的參數(shù)用?來占位(后面參數(shù)必須是oc對象洲愤,颓芭;代表語句結(jié)束)
BOOL result = [_db executeUpdate:@"INSERT INTO t_student (name, age, sex) VALUES (?,?,?)",name,@(age),sex];
//2.executeUpdateWithForamat:不確定的參數(shù)用%@,%d等來占位 (參數(shù)為原始數(shù)據(jù)類型柬赐,執(zhí)行語句不區(qū)分大小寫)
//    BOOL result = [_db executeUpdateWithFormat:@"insert into t_student (name,age, sex) values (%@,%i,%@)",name,age,sex];
//3.參數(shù)是數(shù)組的使用方式
//    BOOL result = [_db executeUpdate:@"INSERT INTO t_student(name,age,sex) VALUES  (?,?,?);" withArgumentsInArray:@[name,@(age),sex]];
if (result) {
    NSLog(@"插入成功");
} else {
    NSLog(@"插入失敗");
}

多插入幾次后亡问,我們可以看到t_student表中添加了多條數(shù)據(jù)

添加的數(shù)據(jù)

PS:如果你需要插入空數(shù)據(jù),比如插入一個student對象肛宋,name為小明州藕,age為16,但是sex暫時不知道酝陈,那么你可以先不加sex床玻,這樣(要注意,對象與 后添?號一定要對應(yīng),不然會報錯的)

[_db executeUpdate:@"INSERT INTO t_student (name, age) VALUES (?,?)",name,@(age)];

同時,也可以在sex中插入一個空值遇西,但是這里的空值不是nil馅精,而是NSNull

[_db executeUpdate:@"INSERT INTO t_student (name, age, sex) VALUES (?,?,?)",name,@(age),[NSNull null]];

5.刪除數(shù)據(jù)

//1.不確定的參數(shù)用?來占位 (后面參數(shù)必須是oc對象,需要將int包裝成OC對象)
int idNum = 11;
BOOL result = [_db executeUpdate:@"delete from t_student where id = ?",@(idNum)];
//2.不確定的參數(shù)用%@粱檀,%d等來占位
//BOOL result = [_db executeUpdateWithFormat:@"delete from t_student where name = %@",@"王子涵"];
if (result) {
    NSLog(@"刪除成功");
} else {
    NSLog(@"刪除失敗");
}

6.修改數(shù)據(jù)

//修改學(xué)生的名字
NSString *newName = @"李浩宇";
NSString *oldName = @"王子涵2";
BOOL result = [_db executeUpdate:@"update t_student set name = ? where name = ?",newName,oldName];
if (result) {
  NSLog(@"修改成功");
} else {
  NSLog(@"修改失敗");
}

查看sqlite洲敢,可以看到王子涵2的姓名已經(jīng)被修改了

王子涵2姓名修改為了李浩宇

PS.上面的sql語句是只修改了對象的一個字段,如果我們需要更新對象的多個乃至全部字段呢茄蚯?這種情況下压彭,我們需要先寫一個格式為NSString的sql語句,將我們需要更新的字段名都寫入其中渗常,然后再調(diào)用另一個executeUpdate方法進(jìn)行更新壮不。代碼如下:

NSString *sql = [NSString stringWithFormat:@"update t_student set name = ?, age = ?, sex = ? where id = ?"];
[_db executeUpdate:sql withArgumentsInArray:@[newName, @(newAge),newSex, @(id)]];

7.查詢數(shù)據(jù)

//查詢整個表
FMResultSet * resultSet = [_db executeQuery:@"select * from t_student"];
//根據(jù)條件查詢
//FMResultSet * resultSet = [_db executeQuery:@"select * from t_student where id < ?", @(4)];
//遍歷結(jié)果集合
while ([resultSet next]) {
     int idNum = [resultSet intForColumn:@"id"];
     NSString *name = [resultSet objectForColumnName:@"name"];
     int age = [resultSet intForColumn:@"age"];
     NSString *sex = [resultSet objectForColumnName:@"sex"];
     NSLog(@"學(xué)號:%@ 姓名:%@ 年齡:%@ 性別:%@",@(idNum),name,@(age),sex);
}

PS:在對FMDB數(shù)據(jù)庫對象的屬性值判斷是否為空時,不能用 nil 來判斷皱碘,而應(yīng)該用null來判斷询一,正確的寫法為

[[resultSet objectForColumnName:@"name"] isKindOfClass:[NSNull Class]];

執(zhí)行查詢之后控制臺的打印,可以看到打印出了目前的所有數(shù)據(jù)

執(zhí)行查詢數(shù)據(jù)后控制臺的打印結(jié)果

8.表的刪除

//如果表格存在 則銷毀
BOOL result = [_db executeUpdate:@"drop table if exists t_student"];
if (result) {
  NSLog(@"刪除表成功");
} else {
  NSLog(@"刪除表失敗");
}

執(zhí)行之后癌椿,刷新SQLite健蕊,可以看到t_student表已經(jīng)被刪除了

刷新SQLite
t_student表被刪除

總結(jié)

以上就是基本的使用方法,希望新手也可以看明白踢俄。此篇文章會不斷更新完善缩功,爭取做到FMDB最最詳細(xì)的介紹,我不嫌啰嗦都办,希望大家也不要嫌啰嗦(畢竟聞道有先后嫡锌,很多時候你寫得太簡單明了籠統(tǒng)了,新手們就比較難理解)脆丁。對應(yīng)的項目也上傳到Github了世舰,大家可以下載下來查看,傳送門:點我

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末槽卫,一起剝皮案震驚了整個濱河市跟压,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌歼培,老刑警劉巖震蒋,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異躲庄,居然都是意外死亡查剖,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門噪窘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笋庄,“玉大人,你說我怎么就攤上這事≈鄙埃” “怎么了菌仁?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長静暂。 經(jīng)常有香客問我济丘,道長,這世上最難降的妖魔是什么洽蛀? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任摹迷,我火速辦了婚禮,結(jié)果婚禮上郊供,老公的妹妹穿的比我還像新娘峡碉。我一直安慰自己,他們只是感情好颂碘,可當(dāng)我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布异赫。 她就那樣靜靜地躺著,像睡著了一般头岔。 火紅的嫁衣襯著肌膚如雪塔拳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天峡竣,我揣著相機(jī)與錄音靠抑,去河邊找鬼。 笑死适掰,一個胖子當(dāng)著我的面吹牛颂碧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播类浪,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼载城,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了费就?” 一聲冷哼從身側(cè)響起诉瓦,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎力细,沒想到半個月后睬澡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡眠蚂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年煞聪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逝慧。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡昔脯,死狀恐怖啄糙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情云稚,我是刑警寧澤迈套,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站碱鳞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏踱蛀。R本人自食惡果不足惜窿给,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望率拒。 院中可真熱鬧崩泡,春花似錦、人聲如沸猬膨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽勃痴。三九已至谒所,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沛申,已是汗流浹背劣领。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留铁材,地道東北人尖淘。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像著觉,于是被迫代替她去往敵國和親村生。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,573評論 2 359

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