闲了好久,不知道写点什么,把最近使用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 , ** 有问题留言**。