
一、主要思想
將整個數(shù)據(jù)模型 model 作為數(shù)據(jù)庫表中的一個鍵值來存儲(在創(chuàng)建表的SQLite語句中model的字段類型為 BLOB,這樣省去了根據(jù)model 的屬性一一對應創(chuàng)建數(shù)據(jù)庫字段)
二、FMDB 簡介
簡介:
FMDB是iOS平臺的SQLite數(shù)據(jù)庫框架,FMDB以OC的方式封裝了SQLite的C語言API
優(yōu)點:
使用起來更加面向對象,省去了很多麻煩、冗余的C語言代碼;對比蘋果自帶的Core Data框架,更加輕量級和靈活;提供了多線程安全的數(shù)據(jù)庫操作方法,有效地防止數(shù)據(jù)混亂
核心類:
FMDatabase:一個 FMDatabase對象就代表一個單獨的SQLite數(shù)據(jù)庫,用來執(zhí)行SQL語句
FMResultSet:使用FMDatabase查詢之后的結果集
FMDatabaseQueue:用于在多線程中執(zhí)行多個查詢或更新,它是線程安全的
三、具體步驟
(一)準備
創(chuàng)建Xcode 測試項目,將FMDB導入項目
(二)FMDB 封裝增刪改查
(1)創(chuàng)建工具類, 引入FMDB頭文件 #import <FMDB/FMDB.h>

(2)創(chuàng)建 NSObject的分類,添加@property (nonatomic, assign) UInt32 user_id; 屬性,使用runtime添加set和get方法
@interface NSObject (Extra)
@property (nonatomic, assign) UInt32 user_id;
@end
@implementation NSObject (Extra)
static NSString *User_Id_Key = @"userIdKey";
- (void)setUser_id:(UInt32)user_id {
objc_setAssociatedObject(self, &User_Id_Key, @(user_id), OBJC_ASSOCIATION_ASSIGN);
}
- (UInt32)user_id {
NSNumber *num = objc_getAssociatedObject(self, &User_Id_Key);
return num.intValue;
}
@end
這里的user_id用來作為model的id,用來當做表數(shù)據(jù)中的主鍵,后面會通過這個id來進行數(shù)據(jù)庫的刪除和修改操作。由于user_id使用了UInt32類型,但是runtime不可以直接添加基本數(shù)據(jù)類型的屬性(會報錯),所以這里我就轉換成了對象
(3)封裝增刪改查方法
創(chuàng)建全局靜態(tài)的FMDatabase成員變量來進行數(shù)據(jù)庫操作
NSString類型的tableName用來存儲表的名稱(當創(chuàng)建多個表的時候,我的這種方法可能會出問題--->未驗證)
@interface DNFMDBTool ()
// 用來存儲數(shù)據(jù)庫表的名稱
@property (nonatomic, copy) NSString *tableName;
@end
static FMDatabase * _db;
創(chuàng)建打開數(shù)據(jù)庫
獲取沙盒路徑創(chuàng)建、打開數(shù)據(jù)庫
- (FMDatabase *)dn_openDatabase {
NSString * path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString * dbPath = [path stringByAppendingPathComponent:@"DNFMDBTools.sqlite"];
_db = [FMDatabase databaseWithPath:dbPath];
if ([_db open]) {
DNLog(@"open dataBase sueccess");
}
return _db;
}
創(chuàng)建表
(這里將表的名字存儲為全局的變量,在創(chuàng)建多張表是可能會出問題)
/** 創(chuàng)建表 */
- (void)dn_createTable:(NSString *)tableName {
self.tableName = tableName;
[self dn_openDatabase];
NSString *sql = [NSString stringWithFormat:@"create table if not exists %@(id integer primary key autoincrement, model BLOB)", self.tableName];
BOOL result = [_db executeUpdate:sql];
if (result) {
DNLog(@"create table success");
}
}
插入數(shù)據(jù)
這里將傳入的將要存儲的model歸檔為 NSData類型,對應存儲為數(shù)據(jù)庫表中的 BLOB類型
- (void)dn_insertData:(id)data {
[self dn_openDatabase];
NSData *modelData = [NSKeyedArchiver archivedDataWithRootObject:data];
NSString *sql = [NSString stringWithFormat:@"insert into %@(model) values (?)", self.tableName];
BOOL result = [_db executeUpdate:sql values:@[modelData] error:nil];
if (result) {
DNLog(@"insert data success");
}
[_db close];
}
刪除數(shù)據(jù)
這里將剛才我們在分類中添加的 user_id作為我們刪除數(shù)據(jù)的標識
- (void)dn_deleteDateUid:(UInt32)uid {
[self dn_openDatabase];
NSString *sql = [NSString stringWithFormat:@"delete from %@ where id = ?", self.tableName];
BOOL result = [_db executeUpdate:sql values:@[@(uid)] error:nil];
if (result) {
DNLog(@"delete data success");
}
[_db close];
}
更新數(shù)據(jù)
這里將傳入進來的model歸檔為data類型,分類中添加的 user_id作為我們更新數(shù)據(jù)的標識
- (void)dn_updateData:(id)data uid:(UInt32)uid {
[self dn_openDatabase];
NSData *modelData = [NSKeyedArchiver archivedDataWithRootObject:data];
NSString * sql = [NSString stringWithFormat:@"update %@ set model = ? where id = ?", self.tableName];
BOOL result = [_db executeUpdate:sql values:@[modelData, @(uid)] error:nil];
if (result) {
DNLog(@"update data success");
} else {
[_db rollback];
}
[_db close];
}
查詢數(shù)據(jù)
利用 FMResultSet查詢數(shù)據(jù)庫得到的結果集,對應獲取數(shù)據(jù)庫中的主鍵id和存儲的數(shù)據(jù)類型model,并將 NSData 類型的modelData 反歸檔,并將對應的model模型放到數(shù)組中返回
- (NSMutableArray *)dn_selectAllData {
[self dn_openDatabase];
NSString *sql = [NSString stringWithFormat:@"select * from %@", self.tableName];
FMResultSet *result = [_db executeQuery:sql];
NSMutableArray *resultArr = [NSMutableArray array];
while (result.next) {
NSObject *model = [[NSObject alloc] init];
// 獲取表中存儲字段對應的值
NSData *modelData = [result dataForColumn:@"model"];
UInt32 uid = [result intForColumn:@"id"];
model = [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:modelData error:nil];
model.user_id = uid;
[resultArr addObject:model];
}
[_db close];
return resultArr;
}
刪除表
- (void)dropTable {
[self dn_openDatabase];
NSString *sql = [NSString stringWithFormat:@"drop table if exists %@", self.tableName];
BOOL result = [_db executeUpdate:sql withArgumentsInArray:@[]];
if (result) {
NSLog(@"drop table success");
}
[_db close];
}
以上就是我關于FMDB封裝的全部內容,歡迎各位大佬指正錯誤。Demo地址