WKweb使用,FMDB讲解和封装

iOS 使用 FMDB 进行本地数据储存

2019-03-11  本文已影响0人  写_Bug_小能手
DNFMDB.gif

一、主要思想

将整个数据模型 model 作为数据库表中的一个键值来存储(在创建表的SQLite语句中model的字段类型为 BLOB,这样省去了根据model 的属性一一对应创建数据库字段)

二、FMDB 简介

简介:
FMDBiOS平台的SQLite数据库框架,FMDBOC的方式封装了SQLiteC语言API

优点:
使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码;对比苹果自带的Core Data框架,更加轻量级和灵活;提供了多线程安全的数据库操作方法,有效地防止数据混乱

核心类:
FMDatabase:一个 FMDatabase对象就代表一个单独的SQLite数据库,用来执行SQL语句
FMResultSet:使用FMDatabase查询之后的结果集
FMDatabaseQueue:用于在多线程中执行多个查询或更新,它是线程安全的

三、具体步骤

(一)准备

创建Xcode 测试项目,将FMDB导入项目

(二)FMDB 封装增删改查

(1)创建工具类, 引入FMDB头文件 #import <FMDB/FMDB.h>

屏幕快照 2019-03-11 17.07.27.png

(2)创建 NSObject的分类,添加@property (nonatomic, assign) UInt32 user_id; 属性,使用runtime添加setget方法

@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用来作为modelid,用来当做表数据中的主键,后面会通过这个id来进行数据库的删除和修改操作。由于user_id使用了UInt32类型,但是runtime不可以直接添加基本数据类型的属性(会报错),所以这里我就转换成了对象
(3)封装增删改查方法
创建全局静态的FMDatabase成员变量来进行数据库操作
NSString类型的tableName用来存储表的名称(当创建多个表的时候,我的这种方法可能会出问题--->未验证)

@interface DNFMDBTool ()
// 用来存储数据库表的名称
@property (nonatomic, copy) NSString *tableName;
@end

static FMDatabase * _db;

创建打开数据库
获取沙盒路径创建、打开数据库

- (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;
}

创建表
(这里将表的名字存储为全局的变量,在创建多张表是可能会出问题)

/** 创建表 */
- (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");
    }
}

插入数据
这里将传入的将要存储的model归档为 NSData类型,对应存储为数据库表中的 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];
}

删除数据
这里将刚才我们在分类中添加的 user_id作为我们删除数据的标识

- (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];
}

更新数据
这里将传入进来的model归档为data类型,分类中添加的 user_id作为我们更新数据的标识

- (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];
}

查询数据
利用 FMResultSet查询数据库得到的结果集,对应获取数据库中的主键id和存储的数据类型model,并将 NSData 类型的modelData 反归档,并将对应的model模型放到数组中返回

- (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地址

上一篇 下一篇

猜你喜欢

热点阅读