閑了好久,不知道寫點什么,把最近使用FMDB的過程寫一下吧!
1. 建立DBManager
建立單例來管理數據庫的創建,開啟,及增刪改查操作。
2. 初始化DataBase,table
使用類屬性創建DataBase及DbQueue
@property (nonatomic, class, readonly) FMDatabase *sharedDataBase;
@property (nonatomic, class, readonly) FMDatabaseQueue *dbQueue;
實現方法
+ (FMDatabase *)sharedDataBase {
static FMDatabase *accountDB = nil;
@synchronized (self) {
if (accountDB == nil) {
NSString *dbPath = [NSHomeDirectory() stringByAppendingFormat:@"/%@",[AccountModel qw_getLocalModel].USERID];
accountDB = [FMDatabase databaseWithPath:dbPath];
if ([accountDB open]) {
DebugLog(@"Database open succeed");
}else{
DebugLog(@"Database open failed");
}
}
}
return accountDB;
}
// 因為FMDB并不是線程安全的,所以建立dbQueue來進行線程操作
static FMDatabaseQueue *_dbQueue = nil;
+ (FMDatabaseQueue *)dbQueue {
if (_dbQueue == nil) {
// dbPath和db的path相同,需要先建立數據庫,才能夠成功創建dbQueue;
NSString *dbPath = [NSHomeDirectory() stringByAppendingFormat:@"/%@",[AccountModel qw_getLocalModel].USERID];
_dbQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
}
return _dbQueue;
}
創建table,根據保存model的類名來創建不同的table
+ (BOOL)createTabelOfClass:(Class)tableClass {
NSString *excuteStr = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@(id, content)", NSStringFromClass(tableClass)];
return [[QWDBManager sharedDataBase] executeStatements:excuteStr];
}
3. 建立Catch
建立一個保存model id的數組,用來查詢數據庫中是否存在該model,減少內存的消耗
@property (nonatomic, strong) NSMutableArray *catchIds;
4. 數據存儲,更新
向table中增加model(非線程安全的)
+ (BOOL)addNewModel:(PostModel *)model {
NSString *addStr = [NSString stringWithFormat:@"INSERT INTO %@ VALUES(?,?)",NSStringFromClass(model.class)];
BOOL ret = [[QWDBManager sharedDataBase] executeUpdate:addStr, [NSString stringWithFormat:@"%ld", (long)model.PostID], [model qw_dataOfModel]];
if(ret){
DebugLog(@"Add model succeed");
}else{
DebugLog(@"Add model failed");
}
return ret;
}
查詢table中是否存在model(非線程安全)第三部分catch的存在就是為了替換掉這個操作,如果有刪除model的需要,可以在查詢完成后進行刪除操作。
+ (BOOL)checkContainModel:(PostModel *)model {
NSString *checkStr = [NSString stringWithFormat:@"SELECT id FROM %@ WHERE id = ?",NSStringFromClass(model.class)];
FMResultSet *resultSet = [[QWDBManager sharedDataBase] executeQuery:checkStr, [NSString stringWithFormat:@"%ld",(long)model.PostID]];
BOOL ret = [resultSet next];
[resultSet close];
return ret;
}
更新model內容(非線程安全)
+ (BOOL)updateModel:(PostModel *)model {
BOOL check = [QWDBManager checkContainModel:model];
if (check) {
NSString *updateStr = [NSString stringWithFormat:@"UPDATE %@ SET content = ? WHERE id = %ld",NSStringFromClass(model.class), (long)model.PostID];
BOOL ret = [[QWDBManager sharedDataBase] executeUpdate:updateStr, [model qw_dataOfModel]];
ret ? DebugLog(@"Update succeed") : DebugLog(@"Update failed");
return ret;
}
return [QWDBManager addNewModel:model];
}
** 實際項目中model一般都是網絡請求到的數據轉換而來的,所以涉及到線程操作,而上面這部分操作都不是線程安全的,所以推薦使用下面的這些方法。**
// 更新model的數組
+ (void)async_updateModels:(NSArray *)models {
[QWDBManager.dbQueue inDatabase:^(FMDatabase *db) {
[models enumerateObjectsUsingBlock:^(PostModel *obj, NSUInteger idx, BOOL * _Nonnull stop) {
// 檢查catch數組中是否存在model id
if ([[QWDBManager shareInstance].catchIds containsObject:@(obj.PostID)]) {
[QWDBManager updateModel:obj inDb:db];
}else{
if ([QWDBManager addModels:obj toBb:db]) [[QWDBManager shareInstance].catchIds addObject:@(obj.PostID)]; // 不存在時,將model id 添加到緩存中
}
if (stop) {
// 更新緩存數據
[[NSUserDefaults standardUserDefaults] setObject:[QWDBManager shareInstance].catchIds forKey:@"CatchModelIdsKey"];
}
}];
}];
}
+ (BOOL)updateModel:(PostModel *)model inDb:(FMDatabase *)db {
NSString *updateStr = [NSString stringWithFormat:@"UPDATE %@ SET content = ? WHERE id = %ld",NSStringFromClass(model.class), (long)model.PostID];
BOOL ret = [db executeUpdate:updateStr, [model qw_dataOfModel]];
if (ret) {
DebugLog(@"Update model:%ld succeed", (long)model.PostID);
}else{
DebugLog(@"Update model:%ld failed", (long)model.PostID);
}
return ret;
}
+ (BOOL)addModels:(PostModel *)model toBb:(FMDatabase *)db {
NSString *addStr = [NSString stringWithFormat:@"INSERT INTO %@ VALUES(?,?)",NSStringFromClass(model.class)];
BOOL ret = [db executeUpdate:addStr, [NSString stringWithFormat:@"%ld", (long)model.PostID], [model qw_dataOfModel]];
if (ret) {
DebugLog(@"Add model:%ld succeed", (long)model.PostID);
}else{
DebugLog(@"Add model:%ld failed", (long)model.PostID);
}
return ret;
}
恩!大致就這樣,最后貼個demo地址:QWPapapa , ** 有問題留言**。