筆記-FMDB

weixin_34239169發表於2018-12-08

簡介

SQLite

一個輕量級的關係型資料庫,SQLite不區分大小寫,但是也有注意的地方,GLOBglob具有不同作用。另外有5中基本資料型別text、integer、real、boolean、blob

SQLite的使用方法

  • 加入libsqlite3.tbd的依賴庫
  • 在檔案中引用#improt<sqlite3.h>標頭檔案
  • 開啟資料庫->建立表->對資料表進行操作->關閉資料庫

FMDB

FMDB是iOS平臺的SQLite資料庫框架,以OC的方式封裝了SQLite的C語言API

FMDB常用的三個類:
FMDataBase:一個FMDatabase物件就代表一個單獨的SQLite資料庫
FMResultSet: 使用FMDatabase執行查詢後的結果集合
FMDatabaseQueue: 用於多執行緒中執行多個查詢或更新,它是執行緒安全的

FMDB的建立和使用方法

  • 下載FMDB(GitHub),然後拖入工程中,也支援pod匯入
  • 在工程中新增libsqlite3.tbd的依賴庫
  • 引入標頭檔案#import "FMDB.h"
  • 程式碼的實現:建立庫路徑->建立資料庫->開啟資料庫->建立表->對資料庫進行操作->關閉資料庫

建立庫路徑

iOS本地優化儲存的資料儲存在沙盒中,並且每個應用的沙盒是相對獨立的,每個應用的沙盒檔案結構都是相同的,如下圖所示:

Documents:iTunes會備份改目錄,一般用來儲存需要持久化的資料。

Library/Caches:快取,iTunes不會備份該目錄。記憶體不足時會被清除,應用沒有執行時,可能會被清除。一般儲存體積大,不需要備份的非重要資料。

Library/Preference:iTunes會備份該目錄,可以用來儲存一些偏好設定。

tmp:iTunes不會備份這個目錄,用來儲存臨時資料,應用退出時會清除該目錄下的資料。

建立路徑

上面的方法有三個引數,說明一下:

NSDocumentDirectory: 第一個引數代表要查詢哪個檔案,是一個列舉,為了直接找到沙盒中的Documents目錄,我們一般用NSDocumentDirectory。

NSUserDomainMask: 也是一個列舉,表示搜尋的範圍限制於當前應用的沙盒目錄。

YES: 第三個引數是一個BOOL值,iOS中主目錄的全寫形式是/User/userName,這個引數填YES就表示全寫,填NO就是“~”,一般使用YES。

通過制定SQLite資料庫檔案的路徑來建立一個FMDatabase,路徑可以是一下幾種方式中的任何一種

  • 完整的路徑,如果路徑不存在,會自動建立。
  • 空字串@"",會自動在快取區建立一個空的資料庫,FMDatabase連線關閉時,資料庫會被自動刪除。
  • 路徑為NULL,會在記憶體中建立一個資料庫,同樣的,在FMDatabase連線關閉時,資料庫會被自動刪除。

開啟資料庫,建立表

使用open語句開啟資料庫,開啟成功返回YES,開啟失敗返回NO

執行資料庫操作

一般情況下,我們最常用的兩個方法

db executeQuery:(NSString*)sql, ...
db executeUpdate:(NSString*)sql, ...
複製程式碼
  • 更新(create、drop、insert、update、delete、alter、commit、begin、detach、explain、vacuum、replace等)
  • 執行(select

關閉資料庫

[db close];
複製程式碼

FMDatabaseQueue

FMDatabase是執行緒不安全的,當FMDB資料儲存想要使用多執行緒的時候,FMDatabaseQueue就能夠用上了。
初始化FMDatabaseQueue的方法與FMDatabase類似

FMDatabaseQueue開啟和關閉資料庫

在初始化的時候FMDatabaseQueue已經將開啟和關閉資料庫封裝好了。所以在運算元據庫的時候不需要單獨呼叫FMDatabaseopenclose方法。

通過網上資料的查詢有關其他API的解讀,這裡說一下

更新

- (BOOL)executeUpdate:(NSString*)sql, ...;
- (BOOL)executeUpdateWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
- (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments;
- (BOOL)executeUpdate:(NSString*)sql values:(NSArray * _Nullable)values error:(NSError * _Nullable __autoreleasing *)error;
- (BOOL)executeUpdate:(NSString*)sql withParameterDictionary:(NSDictionary *)arguments;
- (BOOL)executeUpdate:(NSString*)sql withVAList: (va_list)args;
複製程式碼
查詢

- (FMResultSet * _Nullable)executeQuery:(NSString*)sql, ...;
- (FMResultSet * _Nullable)executeQueryWithFormat:(NSString*)format, ... NS_FORMAT_FUNCTION(1,2);
- (FMResultSet * _Nullable)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)arguments;
- (FMResultSet * _Nullable)executeQuery:(NSString *)sql values:(NSArray * _Nullable)values error:(NSError * _Nullable __autoreleasing *)error;
- (FMResultSet * _Nullable)executeQuery:(NSString *)sql withParameterDictionary:(NSDictionary * _Nullable)arguments;
- (FMResultSet * _Nullable)executeQuery:(NSString *)sql withVAList:(va_list)args;
複製程式碼

方法解讀:

1、如果需要插入基礎資料型別,要麼自己做一下轉換,要麼呼叫以下方法
- (FMResultSet * _Nullable)executeQueryWithFormat:(NSString*)format, ... NS_FORMAT_FUNCTION(1,2);

[_dataBaseQueue inDatabase:^(FMDatabase * _Nonnull db) {
    [db executeUpdateWithFormat:@"INSERT INTO usertable VALUES (%d, %@ , %d)", 1, @"lizhiqiang", 25];
}];


2、這個沒什麼可說的,陣列引數,直接上程式碼
- (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments;

[_dataBaseQueue inDatabase:^(FMDatabase * _Nonnull db) {
    [db executeUpdate:@"INSERT INTO usertable VALUES (?, ? , ?)" withArgumentsInArray:@[@2, @"yanghuixue", @26]];
}];


3、比方法2多了error指標引數,記錄更新失敗
- (BOOL)executeUpdate:(NSString*)sql values:(NSArray * _Nullable)values error:(NSError * _Nullable __autoreleasing *)error;


4、注意,這個mark一下,引數為字典,寫法變了,並且插入欄位必須與字典key相對應
- (BOOL)executeUpdate:(NSString*)sql withParameterDictionary:(NSDictionary *)arguments;

NSDictionary *testDict = @{
                           @"id" : @14,
                           @"name" : @"ly",
                           @"age" : @15
                           };
[_dataBaseQueue inDatabase:^(FMDatabase * _Nonnull db) {
    [db executeUpdate:@"INSERT INTO usertable VALUES(:id, :name, :age)" withParameterDictionary:testDict];
}];


5、va_list是C語言中解決變參問題的一組巨集
- (BOOL)executeUpdate:(NSString*)sql withVAList: (va_list)args;
複製程式碼

批處理:可以通過呼叫executeStatements方法,一次執行多個sql語句

- (BOOL)executeStatements:(NSString *)sql;
- (BOOL)executeStatements:(NSString *)sql withResultBlock:(__attribute__((noescape)) FMDBExecuteStatementsCallbackBlock _Nullable)block;

例:
NSString *creatSqlString = @"CREATE TABLE IF NOT EXISTS grouptable(id INTEGER, gcid VARCHAR(64), gcname VARCHAR(64));"
@"CREATE TABLE IF NOT EXISTS usertable(id INTEGER, name VARCHAT(1024), age INTEGER)";

[_dataBaseQueue inDatabase:^(FMDatabase *db) {
    [db executeStatements:creatSqlString];
}];
複製程式碼

事務

事務(Transaction)是不可分割的一個整體操作,要麼都執行,要麼都不執行。

事務裡有回滾操作,當一個整體事務在執行的時候,中間任何一個環節出現問題,則執行回滾,然後整個事務中的所有操作將無效。

FMDatabase使用事務的方法:

FMDatabaseQueue使用事務的方法:

關於SQLite的其他知識點的總結點選這裡前往

參考文獻:
FMDB進階
FMDB理論和實踐
最全iOS資料儲存方法介紹