FMDB的使用

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

你可能感兴趣的:(FMDB的使用)