Github 地址: FMDB
由于 SQLite3 使用比較麻煩, 所以推薦使用第三方開源庫FMDB , 他以 OC 的方式封裝了SQLite 的C 語言 API.
優(yōu)點:
- 使用起來更加面向?qū)ο蟠次耄∪チ撕芏嗦闊⑷哂嗟腃語言代碼
- 對比蘋果自帶的Core Data框架葛躏,更加輕量級和靈活
- 提供了多線程安全的數(shù)據(jù)庫操作方法奈应,有效地防止數(shù)據(jù)混亂
核心類
FMDB有三個主要的類:
- FMDatabase
一個FMDatabase對象就代表一個單獨的SQLite數(shù)據(jù)庫彤侍,用來執(zhí)行SQL語句
- FMResultSet
使用FMDatabase執(zhí)行查詢后的結(jié)果集
- FMDatabaseQueue
用于在多線程中執(zhí)行多個查詢或更新,它是線程安全的
打開數(shù)據(jù)庫
和c語言框架一樣,F(xiàn)MDB通過指定SQLite數(shù)據(jù)庫文件路徑來創(chuàng)建FMDatabase對象食拜,但FMDB更加容易理解,使用起來更容易副编,使用之前一樣需要導(dǎo)入sqlite3.dylib
负甸。打開數(shù)據(jù)庫方法如下:
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"person.db"];
FMDatabase *database = [FMDatabase databaseWithPath:path];
if (![database open]) {
NSLog(@"數(shù)據(jù)庫打開失敗痹届!");
}
path
的值可以傳入以下三種:
- 具體文件路徑呻待,如果不存在會自動創(chuàng)建
- 空字符串@"",會在臨時目錄創(chuàng)建一個空的數(shù)據(jù)庫队腐,當(dāng)FMDatabase連接關(guān)閉時蚕捉,數(shù)據(jù)庫文件也被刪除
- nil,會創(chuàng)建一個內(nèi)存中臨時數(shù)據(jù)庫柴淘,當(dāng)FMDatabase連接關(guān)閉時迫淹,數(shù)據(jù)庫會被銷毀
更新
在FMDB中秘通,除查詢以外的所有操作,都稱為“更新”, 如:create
敛熬、drop
充易、insert
、update
荸型、delete
等操作盹靴,使用executeUpdate:
方法執(zhí)行更新:
//常用方法有以下3種:
- (BOOL)executeUpdate:(NSString*)sql, ...
- (BOOL)executeUpdateWithFormat:(NSString*)format, ...
- (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments
//示例
[database executeUpdate:@"CREATE TABLE IF NOT EXISTS t_person(id integer primary key autoincrement, name text, age integer)"];
//或者
[database executeUpdate:@"INSERT INTO t_person(name, age) VALUES(?, ?)", @"Bourne", [NSNumber numberWithInt:42]];
查詢
- (FMResultSet *)executeQuery:(NSString*)sql, ...
- (FMResultSet *)executeQueryWithFormat:(NSString*)format, ...
- (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)arguments
例:
FMResultSet *result = [database executeQuery:@"SELECT * FROM t_person"];
//2.遍歷結(jié)果集
while ([result next]) {
NSString *name = [result stringForColumn:@"name"];
int age = [result intForColumn:@"age"];
}
CocoaPods
pod 'FMDB'
# pod 'FMDB/FTS' # FMDB with FTS
# pod 'FMDB/standalone' # FMDB with latest SQLite amalgamation source
# pod 'FMDB/standalone/FTS' # FMDB with latest SQLite amalgamation source and FTS
# pod 'FMDB/SQLCipher' # FMDB with SQLCipher
多條語句與批處理
可以將多條語句放在一起執(zhí)行
NSString *sql = @"create table bulktest1 (id integer primary key autoincrement, x text);"
"create table bulktest2 (id integer primary key autoincrement, y text);"
"create table bulktest3 (id integer primary key autoincrement, z text);"
"insert into bulktest1 (x) values ('XXX');"
"insert into bulktest2 (y) values ('YYY');"
"insert into bulktest3 (z) values ('ZZZ');";
success = [db executeStatements:sql];
sql = @"select count(*) as count from bulktest1;"
"select count(*) as count from bulktest2;"
"select count(*) as count from bulktest3;";
success = [self.db executeStatements:sql withResultBlock:^int(NSDictionary *dictionary) {
NSInteger count = [dictionary[@"count"] integerValue];
XCTAssertEqual(count, 1, @"expected one record for dictionary %@", dictionary);
return 0;
}];
使用FMDataBaseQueue 和線程安全
不要讓多個線程分享同一個FMDatabase實例,它無法在多個線程中同時使用瑞妇。 如果在多個線程中同時使用一個FMDatabase實例稿静,會造成數(shù)據(jù)混亂等問題。所以辕狰,請使用 FMDatabaseQueue改备,它是線程安全的。
- 創(chuàng)建隊列
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
- 使用隊列
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @1];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @2];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @3];
FMResultSet *rs = [db executeQuery:@"select * from foo"];
while ([rs next]) {
…
}
}];
- 把任務(wù)包裝到事務(wù)里
[queue inTransaction:^(FMDatabase *database, BOOL *rollback) {
[database executeUpdate:@"INSERT INTO t_person(name, age) VALUES (?, ?)", @"Bourne_1", [NSNumber numberWithInt:1]];
[database executeUpdate:@"INSERT INTO t_person(name, age) VALUES (?, ?)", @"Bourne_2", [NSNumber numberWithInt:2]];
[database executeUpdate:@"INSERT INTO t_person(name, age) VALUES (?, ?)", @"Bourne_3", [NSNumber numberWithInt:3]];
FMResultSet *result = [database executeQuery:@"select * from t_person"];
while([result next]) {
}
//回滾
*rollback = YES;
}];
FMDatabaseQueue 后臺會建立系列化的G-C-D隊列蔓倍,并執(zhí)行你傳給G-C-D隊列的塊悬钳。這意味著 你從多線程同時調(diào)用調(diào)用方法,GDC也會按它接收的塊的順序來執(zhí)行偶翅。