[iOS]數據庫第三方框架FMDB詳細講解
初識FMDB
iOS中原生的SQLite
API在進行數據存儲的時候,需要使用C語言中的函數,操作比較麻煩。于是,就出現了一系列將SQLite API進行封裝的庫,例如FMDB
、PlausibleDatabase
、sqlitepersistentobjects
等。
FMDB是一款簡潔、易用的封裝庫。因此,在這里推薦使用第三方框架FMDB,它是對libsqlite3框架的封裝,用起來的步驟與SQLite使用類似,并且它對于多線程的并發操作進行了處理,所以是線程安全的。
FMDB PK Sqlite
- 優點:
- 對多線程的并發操作進行處理,所以是線程安全的;
- 以OC的方式封裝了
SQLite
的C語言API,使用起來更加的方便; - FMDB是輕量級的框架,使用靈活。
- 缺點:
- 因為它是OC的語言封裝的,只能在ios開發的時候使用,所以在實現跨平臺操作的時候存在局限性。
FMDB框架中重要的框架類
-
FMDatabase
-
FMDatabase
對象就代表一個單獨的SQLite
數據庫,用來執行SQL
語句
-
-
FMResultSet
- 使用
FMDatabase
執行查詢后的結果集
- 使用
-
FMDatabaseQueue
- 用于在多線程中執行多個查詢或更新,它是線程安全的
FMDB使用步驟
- 下載FMDB文件GitHub,并將FMDB文件夾添加到項目中(也可使用CocoaPods導入)
- 導入
libsqlite3.0
框架,導入頭文件FMDatabase.h
- 代碼實現,與SQLite使用步驟相似,創建數據庫路徑,獲得數據庫路徑,打開數據庫,然后對數據庫進行增、刪、改、查操作,最后關閉數據庫。
數據庫創建
創建FMDatabase對象時參數為SQLite數據庫文件路徑,該路徑可以是以下三種方式之一
文件路徑。該文件路徑無需真實存在,如果不存在會自動創建
空字符串(@“”)。表示會在臨時目錄創建一個空的數據庫,當FMDatabase連接關閉時,文件也會被刪除
NULL。將創建一個內在數據庫,同樣的,當FMDatabase連接關閉時,數據將會被銷毀
本文中使用的測試模型類.h
數據庫使用FMDB
框架代碼操作
-
使用
FMDataBase
類建立數據庫//1.獲得數據庫文件的路徑 NSString *doc =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) lastObject]; NSString *fileName = [doc stringByAppendingPathComponent:@“student.sqlite”]; //2.獲得數據庫 FMDatabase *db = [FMDatabase databaseWithPath:fileName]; //3.使用如下語句,如果打開失敗,可能是權限不足或者資源不足。通常打開完操作操作后,需要調用 close 方法來關閉數據庫。在和數據庫交互 之前,數據庫必須是打開的。如果資源或權限不足無法打開或創建數據庫,都會導致打開失敗。 if ([db open]) { //4.創表 BOOL result = [db executeUpdate:@“CREATE TABLE IF NOT EXISTS t_student (id integer PRIMARY KEY AUTOINCREMENT, name text NOT NULL, age integer NOT NULL);”]; if (result) { NSLog(@“創建表成功”); } }
查看sql表
根據路徑fileName在Finder中搜索.sqlite文件,并復制到桌面
-
使用火狐瀏覽器工具下的SQLite Manager打開.sqlite文件
2.png 數據表結構
使用FMDataBase
類執行數據庫命令SQL
一切不是SELECT命令的命令都視為更新。這包括 CREAT,UPDATE,INSERT,ALTER,BEGIN,COMMIT,DETACH,DELETE,DROP,END,EXPLAIN,VACUUM,REPLACE等。
簡單來說,只要不是以SELECT開頭的命令都是更新命令。
執行更新返回一個BOOL值。YES表示 執行成功,否則表示有錯誤。你可以調用 -lastErrorMessage 和 -lastErrorCode方法來得到更多信息。
-
使用
FMDataBase
類執行數據庫插入命令SQLinsert into
int age = 42; //1.executeUpdate:不確定的參數用?來占位(后面參數必須是oc對象,;代表語句結束) [self.db executeUpdate:@“INSERT INTO t_student (name, age) VALUES (?,?);”,name,@(age)]; //2.executeUpdateWithForamat:不確定的參數用%@,%d等來占位 (參數為原始數據類型,執行語句不區分大小寫) [self.db executeUpdateWithForamat:@“insert into t_student (name,age) values (%@,%i);”,name,age]; //3.參數是數組的使用方式 [self.db executeUpdate:@“INSERT INTO t_student(name,age) VALUES (?,?);”withArgumentsInArray:@[name,@(age )]];
-
使用
FMDataBase
類執行數據庫刪除命令SQLdelete
//1.不確定的參數用?來占位 (后面參數必須是oc對象,需要將int包裝成OC對象) int idNum = 101; [self.db executeUpdate:@“delete from t_student where id = ?;”,@(idNum)]; //2.不確定的參數用%@,%d等來占位 [self.db executeUpdateWithFormat:@“delete from t_student where name = %@;”,@“apple_name”];
-
使用
FMDataBase
類執行數據庫修改命令SQLupdate
//修改學生的名字 [self.db executeUpdate:@“update t_student set name = ? where name = ?”,newName,oldName];
-
使用
FMDataBase
類執行數據庫查詢命令SQLselect ... from
- SELECT命令就是查詢,執行查詢的方法是以-excuteQuery開頭的。
- 執行查詢時,如果成功返回FMResultSet對象,錯誤返回nil。與執行更新相當,支持使用NSError參數。
- 同時,你也可以使用-lastErrorCode和-lastErrorMessage獲知錯誤信息。
FMResultSet
獲取不同數據格式的方法intForColumn:
longForColumn:
longLongIntForColumn:
boolForColumn:
doubleForColumn:
stringForColumn:
dataForColumn:
dataNoCopyForColumn:
UTF8StringForColumnIndex:
objectForColumn:
-
使用
FMResultSet
獲取查詢語句結果//查詢整個表 FMResultSet *resultSet = [self.db executeQuery:@“select * from t_student;”]; //根據條件查詢 FMResultSet *resultSet = [self.db executeQuery:@“select * from t_student where id<?;”@(14)]; //遍歷結果集合 while ([resultSet next]) { int idNum = [resultSet intForColumn:@“id”]; NSString *name = [resultSet objectForColumn:@“name”]; int age = [resultSet intForColumn:@“age”]; }
-
使用
FMDataBase
類執行數據庫銷毀命令SQLdrop ...
//如果表格存在 則銷毀 [self.db executeUpadate:@“drop table if exists t_student;”];
使用
FMDatabaseQueue
類實現多線程操作
在多個線程中同時使用一個FMDatabase實例是不明智的。現在你可以為每 個線程創建一個FMDatabase對象,不要讓多個線程分享同一個實例,他無 法在多個線程中同事使用。否則程序會時不時崩潰或者報告異常。所以,不要 初始化FMDatabase對象,然后在多個線程中使用。這時候,我們就需要使 用FMDatabaseQueue來創建隊列執行事務。
//1.創建隊列
FMDatabaseQueue *queue = [FMDatabaseQueue
databaseQueueWithPath:aPath];
__block BOOL whoopsSomethingWrongHappened = true;
//2.把任務包裝到事務里
[queue inTransaction:^(FMDatabase *db, BOOL *rollback)
{
whoopsSomethingWrongHappened &= [db executeUpdate:@“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;
}
}];
好了,到此為止,相信你已經能夠使用FMDB進行數據持久化了,它的好與壞 只有在不斷地使用過程中才能發現了解。所以,希望大家學會了以后還是要多 寫多練多使用。另外,誠心希望大家多提寶貴意見,或者溝通一些好的想法。^^