前一篇文章写了FMDB语法的基本语法,主要用于初步在学习阶段使用,要想正式使用的时候,我们肯定不能一句句的去写那些复杂的代码,最近有几个项目用到了FMDB,正好整理封装了一下,使用更方便。
采用单例模式,在想使用的类中加入 #import "YJFMDB.h" 。使用的时候直接调用,如:
保存:[[YJFMDB shareDatabase] YJ_saveTable:@"tableName" dicOrModel:dict];
所有方法在.h中有详细的注释,可根据自己具体的使用情况进行扩展、
另外一个需要注意的就是在程序第一次使用,或者本地不存在数据库的时候进行创建表的操作。这个需要提前知道表结构,代码如下:
if (![[JQFMDB shareDatabase]YJ_isExistTable:@"TableName"]) {//无表则建表
BOOL success = [[JQFMDB shareDatabase]YJ_createTable:@"TableName" dicOrModel:@{@"type_name":@"TEXT",@"type_icon_name":@"TEXT",@"kind":@"TEXT"}];
NSLog(@"---建表%@",success?@"成功!":@"失败!");
}
下面贴上具体的.h中的方法介绍:
YJFMDB.h
#import
@interface YJFMDB : NSObject
/**
(主键id,自动创建) 返回最后插入的primary key id
@param tableName 表的名称
*/
- (NSInteger)lastInsertPrimaryKeyId:(NSString *)tableName;
/**
单例方法创建数据库, 如果使用shareDatabase创建,则默认在NSDocumentDirectory下创建JQFMDB.sqlite, 但只要使用这三个方法任意一个创建成功, 之后即可使用三个中任意一个方法获得同一个实例,参数可随意或nil
dbName 数据库的名称 如: @"Users.sqlite", 如果dbName = nil,则默认dbName=@"JQFMDB.sqlite"
dbPath 数据库的路径, 如果dbPath = nil, 则路径默认为NSDocumentDirectory
*/
+ (instancetype)shareDatabase;
+ (instancetype)shareDatabase:(NSString *)dbName;
+ (instancetype)shareDatabase:(NSString *)dbName path:(NSString *)dbPath;
/**
非单例方法创建数据库
@param dbName 数据库的名称 如: @"Users.sqlite"
dbPath 数据库的路径, 如果dbPath = nil, 则路径默认为NSDocumentDirectory
*/
- (instancetype)initWithDBName:(NSString *)dbName;
- (instancetype)initWithDBName:(NSString *)dbName path:(NSString *)dbPath;
/**
创建表 通过传入的model或dictionary(如果是字典注意类型要写对),虽然都可以不过还是推荐以下都用model
@param tableName 表的名称
@param parameters 设置表的字段,可以传model(runtime自动生成字段)或字典(格式:@{@"name":@"TEXT"})
@return 是否创建成功
*/
- (BOOL)YJ_createTable:(NSString *)tableName dicOrModel:(id)parameters;
/**
同上,
@param nameArr 不允许model或dic里的属性/key生成表的字段,如:nameArr = @[@"name"],则不允许名为name的属性/key 生成表的字段
*/
- (BOOL)YJ_createTable:(NSString *)tableName dicOrModel:(id)parameters excludeName:(NSArray *)nameArr;
/**
增加: 向表中插入数据
@param tableName 表的名称
@param parameters 要插入的数据,可以是model或dictionary(格式:@{@"name":@"小李"})
@return 是否插入成功
*/
- (BOOL)YJ_saveTable:(NSString *)tableName dicOrModel:(id)parameters;
/**
删除: 根据条件删除表中数据
@param tableName 表的名称
@param format 条件语句, 如:@"where name = '小李'"
@return 是否删除成功
*/
- (BOOL)YJ_deleteTable:(NSString *)tableName whereFormat:(NSString *)format, ...;
/**
更改: 根据条件更改表中数据
@param tableName 表的名称
@param parameters 要更改的数据,可以是model或dictionary(格式:@{@"name":@"张三"})
@param format 条件语句, 如:@"where name = '小李'"
@return 是否更改成功
*/
- (BOOL)YJ_updateTable:(NSString *)tableName dicOrModel:(id)parameters whereFormat:(NSString *)format, ...;
/**
查找: 根据条件查找表中数据
@param tableName 表的名称
@param parameters 每条查找结果放入model(可以是[Person class] or @"Person" or Person实例)或dictionary中
@param format 条件语句, 如:@"where name = '小李'",
@return 将结果存入array,数组中的元素的类型为parameters的类型
*/
- (NSArray *)YJ_findTable:(NSString *)tableName dicOrModel:(id)parameters whereFormat:(NSString *)format, ...;
/**
批量插入或更改
@param dicOrModelArray 要insert/update数据的数组,也可以将model和dictionary混合装入array
@return 返回的数组存储未插入成功的下标,数组中元素类型为NSNumber
*/
- (NSArray *)YJ_saveTable:(NSString *)tableName dicOrModelArray:(NSArray *)dicOrModelArray;
// `删除表
- (BOOL)YJ_deleteTable:(NSString *)tableName;
// `清空表
- (BOOL)YJ_deleteAllDataFromTable:(NSString *)tableName;
// `是否存在表
- (BOOL)YJ_isExistTable:(NSString *)tableName;
// `表中共有多少条数据
- (int)YJ_tableItemCount:(NSString *)tableName;
// `返回表中的字段名
- (NSArray *)YJ_columnNameArray:(NSString *)tableName;
// `关闭数据库
- (void)close;
// `打开数据库 (每次shareDatabase系列操作时已经open,当调用close后若进行db操作需重新open或调用shareDatabase)
- (void)open;
/**
增加新字段, 在建表后还想新增字段,可以在原建表model或新model中新增对应属性,然后传入即可新增该字段,该操作已在事务中执行
@param tableName 表的名称
@param parameters 如果传Model:数据库新增字段为建表时model所没有的属性,如果传dictionary格式为@{@"newname":@"TEXT"}
@param nameArr 不允许生成字段的属性名的数组
@return 是否成功
*/
- (BOOL)YJ_alterTable:(NSString *)tableName dicOrModel:(id)parameters excludeName:(NSArray *)nameArr;
- (BOOL)YJ_alterTable:(NSString *)tableName dicOrModel:(id)parameters;
// ============================= 线程安全操作 ===============================
/**
将操作语句放入block中即可保证线程安全, 如:
Person *p = [[Person alloc] init];
p.name = @"小李";
[jqdb jq_inDatabase:^{
[jqdb jq_insertTable:@"users" dicOrModel:p];
}];
*/
- (void)YJ_inDatabase:(void (^)(void))block;
/**
事务: 将操作语句放入block中可执行回滚操作(*rollback = YES;)
Person *p = [[Person alloc] init];
p.name = @"小李";
for (int i=0,i < 1000,i++) {
[jq jq_inTransaction:^(BOOL *rollback) {
BOOL flag = [jq jq_insertTable:@"users" dicOrModel:p];
if (!flag) {
*rollback = YES; //只要有一次不成功,则进行回滚操作
return;
}
}];
}
*/
- (void)YJ_inTransaction:(void(^)(BOOL *rollback))block;
@end
YJFMDB.m
#import "YJFMDB.h"
#import "FMDB.h"
#import
// 数据库中常见的几种类型
#define SQL_TEXT @"TEXT" //文本
#define SQL_INTEGER @"INTEGER" //int long integer ...
#define SQL_REAL @"REAL" //浮点
#define SQL_BLOB @"BLOB" //data
@interface YJFMDB()
@property (nonatomic, strong)NSString *dbPath;
@property (nonatomic, strong)FMDatabaseQueue *dbQueue;
@property (nonatomic, strong)FMDatabase *db;
@end
@implementation YJFMDB
- (FMDatabaseQueue *)dbQueue
{
if (!_dbQueue) {
FMDatabaseQueue *fmdb = [FMDatabaseQueue databaseQueueWithPath:_dbPath];
self.dbQueue = fmdb;
[_db close];
self.db = [fmdb valueForKey:@"_db"];
}
return _dbQueue;
}
static YJFMDB *jqdb = nil;
+ (instancetype)shareDatabase
{
return [YJFMDB shareDatabase:nil];
}
+ (instancetype)shareDatabase:(NSString *)dbName
{
return [YJFMDB shareDatabase:dbName path:nil];
}
+ (instancetype)shareDatabase:(NSString *)dbName path:(NSString *)dbPath
{
if (!jqdb) {
NSString *path;
if (!dbName) {
dbName = @"JQFMDB.sqlite";
}
if (!dbPath) {
path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:dbName];
} else {
path = [dbPath stringByAppendingPathComponent:dbName];
}
FMDatabase *fmdb = [FMDatabase databaseWithPath:path];
if ([fmdb open]) {
jqdb = YJFMDB.new;
jqdb.db = fmdb;
jqdb.dbPath = path;
}
}
if (![jqdb.db open]) {
NSLog(@"database can not open !");
return nil;
};
return jqdb;
}
- (instancetype)initWithDBName:(NSString *)dbName
{
return [self initWithDBName:dbName path:nil];
}
- (instancetype)initWithDBName:(NSString *)dbName path:(NSString *)dbPath
{
if (!dbName) {
dbName = @"YJFMDB.sqlite";
}
NSString *path;
if (!dbPath) {
path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:dbName];
} else {
path = [dbPath stringByAppendingPathComponent:dbName];
}
FMDatabase *fmdb = [FMDatabase databaseWithPath:path];
if ([fmdb open]) {
self = [self init];
if (self) {
self.db = fmdb;
self.dbPath = path;
return self;
}
}
return nil;
}
-(BOOL)YJ_createTable:(NSString *)tableName dicOrModel:(id)parameters{
return [self YJ_createTable:tableName dicOrModel:parameters excludeName:nil];
}
-(BOOL)YJ_createTable:(NSString *)tableName dicOrModel:(id)parameters excludeName:(NSArray *)nameArr{
NSDictionary *dic;
if ([parameters isKindOfClass:[NSDictionary class]]) {
dic = parameters;
} else {
Class CLS;
if ([parameters isKindOfClass:[NSString class]]) {
if (!NSClassFromString(parameters)) {
CLS = nil;
} else {
CLS = NSClassFromString(parameters);
}
} else if ([parameters isKindOfClass:[NSObject class]]) {
CLS = [parameters class];
} else {
CLS = parameters;
}
dic = [self modelToDictionary:CLS excludePropertyName:nameArr];
}
NSMutableString *fieldStr = [[NSMutableString alloc] initWithFormat:@"CREATE TABLE %@ (pkid INTEGER PRIMARY KEY,", tableName];
int keyCount = 0;
for (NSString *key in dic) {
keyCount++;
if ((nameArr && [nameArr containsObject:key]) || [key isEqualToString:@"pkid"]) {
continue;
}
if (keyCount == dic.count) {
[fieldStr appendFormat:@" %@ %@)", key, dic[key]];
break;
}
[fieldStr appendFormat:@" %@ %@,", key, dic[key]];
}
BOOL creatFlag;
creatFlag = [_db executeUpdate:fieldStr];
return creatFlag;
}
- (NSString *)createTable:(NSString *)tableName dictionary:(NSDictionary *)dic excludeName:(NSArray *)nameArr
{
NSMutableString *fieldStr = [[NSMutableString alloc] initWithFormat:@"CREATE TABLE %@ (pkid INTEGER PRIMARY KEY,", tableName];
int keyCount = 0;
for (NSString *key in dic) {
keyCount++;
if ((nameArr && [nameArr containsObject:key]) || [key isEqualToString:@"pkid"]) {
continue;
}
if (keyCount == dic.count) {
[fieldStr appendFormat:@" %@ %@)", key, dic[key]];
break;
}
[fieldStr appendFormat:@" %@ %@,", key, dic[key]];
}
return fieldStr;
}
- (NSString *)createTable:(NSString *)tableName model:(Class)cls excludeName:(NSArray *)nameArr
{
NSMutableString *fieldStr = [[NSMutableString alloc] initWithFormat:@"CREATE TABLE %@ (pkid INTEGER PRIMARY KEY,", tableName];
NSDictionary *dic = [self modelToDictionary:cls excludePropertyName:nameArr];
int keyCount = 0;
for (NSString *key in dic) {
keyCount++;
if ([key isEqualToString:@"pkid"]) {
continue;
}
if (keyCount == dic.count) {
[fieldStr appendFormat:@" %@ %@)", key, dic[key]];
break;
}
[fieldStr appendFormat:@" %@ %@,", key, dic[key]];
}
return fieldStr;
}
#pragma mark - *************** runtime
- (NSDictionary *)modelToDictionary:(Class)cls excludePropertyName:(NSArray *)nameArr
{
NSMutableDictionary *mDic = [NSMutableDictionary dictionaryWithCapacity:0];
unsigned int outCount;
objc_property_t *properties = class_copyPropertyList(cls, &outCount);
for (int i = 0; i < outCount; i++) {
NSString *name = [NSString stringWithCString:property_getName(properties[i]) encoding:NSUTF8StringEncoding];
if ([nameArr containsObject:name]) continue;
NSString *type = [NSString stringWithCString:property_getAttributes(properties[i]) encoding:NSUTF8StringEncoding];
id value = [self propertTypeConvert:type];
if (value) {
[mDic setObject:value forKey:name];
}
}
free(properties);
return mDic;
}
// 获取model的key和value
- (NSDictionary *)getModelPropertyKeyValue:(id)model tableName:(NSString *)tableName clomnArr:(NSArray *)clomnArr
{
NSMutableDictionary *mDic = [NSMutableDictionary dictionaryWithCapacity:0];
unsigned int outCount;
objc_property_t *properties = class_copyPropertyList([model class], &outCount);
for (int i = 0; i < outCount; i++) {
NSString *name = [NSString stringWithCString:property_getName(properties[i]) encoding:NSUTF8StringEncoding];
if (![clomnArr containsObject:name]) {
continue;
}
id value = [model valueForKey:name];
if (value) {
[mDic setObject:value forKey:name];
}
}
free(properties);
return mDic;
}
- (NSString *)propertTypeConvert:(NSString *)typeStr
{
NSString *resultStr = nil;
if ([typeStr hasPrefix:@"T@\"NSString\""]) {
resultStr = SQL_TEXT;
} else if ([typeStr hasPrefix:@"T@\"NSData\""]) {
resultStr = SQL_BLOB;
} else if ([typeStr hasPrefix:@"Ti"]||[typeStr hasPrefix:@"TI"]||[typeStr hasPrefix:@"Ts"]||[typeStr hasPrefix:@"TS"]||[typeStr hasPrefix:@"T@\"NSNumber\""]||[typeStr hasPrefix:@"TB"]||[typeStr hasPrefix:@"Tq"]||[typeStr hasPrefix:@"TQ"]) {
resultStr = SQL_INTEGER;
} else if ([typeStr hasPrefix:@"Tf"] || [typeStr hasPrefix:@"Td"]){
resultStr= SQL_REAL;
}
return resultStr;
}
// 得到表里的字段名称
- (NSArray *)getColumnArr:(NSString *)tableName db:(FMDatabase *)db
{
NSMutableArray *mArr = [NSMutableArray arrayWithCapacity:0];
FMResultSet *resultSet = [db getTableSchema:tableName];
while ([resultSet next]) {
[mArr addObject:[resultSet stringForColumn:@"name"]];
}
return mArr;
}
#pragma mark - *************** 增删改查
-(BOOL)YJ_saveTable:(NSString *)tableName dicOrModel:(id)parameters{
NSArray *columnArr = [self getColumnArr:tableName db:_db];
return [self insertTable:tableName dicOrModel:parameters columnArr:columnArr];
}
- (BOOL)insertTable:(NSString *)tableName dicOrModel:(id)parameters columnArr:(NSArray *)columnArr
{
BOOL flag;
NSDictionary *dic;
if ([parameters isKindOfClass:[NSDictionary class]]) {
dic = parameters;
}else {
dic = [self getModelPropertyKeyValue:parameters tableName:tableName clomnArr:columnArr];
}
NSMutableString *finalStr = [[NSMutableString alloc] initWithFormat:@"INSERT INTO %@ (", tableName];
NSMutableString *tempStr = [NSMutableString stringWithCapacity:0];
NSMutableArray *argumentsArr = [NSMutableArray arrayWithCapacity:0];
for (NSString *key in dic) {
if (![columnArr containsObject:key] || [key isEqualToString:@"pkid"]) {
continue;
}
[finalStr appendFormat:@"%@,", key];
[tempStr appendString:@"?,"];
[argumentsArr addObject:dic[key]];
}
[finalStr deleteCharactersInRange:NSMakeRange(finalStr.length-1, 1)];
if (tempStr.length)
[tempStr deleteCharactersInRange:NSMakeRange(tempStr.length-1, 1)];
[finalStr appendFormat:@") values (%@)", tempStr];
flag = [_db executeUpdate:finalStr withArgumentsInArray:argumentsArr];
return flag;
}
-(BOOL)YJ_deleteTable:(NSString *)tableName whereFormat:(NSString *)format, ...{
va_list args;
va_start(args, format);
NSString *where = format?[[NSString alloc] initWithFormat:format locale:[NSLocale currentLocale] arguments:args]:format;
va_end(args);
BOOL flag;
NSMutableString *finalStr = [[NSMutableString alloc] initWithFormat:@"delete from %@ %@", tableName,where];
flag = [_db executeUpdate:finalStr];
return flag;
}
-(BOOL)YJ_updateTable:(NSString *)tableName dicOrModel:(id)parameters whereFormat:(NSString *)format, ...{
va_list args;
va_start(args, format);
NSString *where = format?[[NSString alloc] initWithFormat:format locale:[NSLocale currentLocale] arguments:args]:format;
va_end(args);
BOOL flag;
NSDictionary *dic;
NSArray *clomnArr = [self getColumnArr:tableName db:_db];
if ([parameters isKindOfClass:[NSDictionary class]]) {
dic = parameters;
}else {
dic = [self getModelPropertyKeyValue:parameters tableName:tableName clomnArr:clomnArr];
}
NSMutableString *finalStr = [[NSMutableString alloc] initWithFormat:@"update %@ set ", tableName];
NSMutableArray *argumentsArr = [NSMutableArray arrayWithCapacity:0];
for (NSString *key in dic) {
if (![clomnArr containsObject:key] || [key isEqualToString:@"pkid"]) {
continue;
}
[finalStr appendFormat:@"%@ = %@,", key, @"?"];
[argumentsArr addObject:dic[key]];
}
[finalStr deleteCharactersInRange:NSMakeRange(finalStr.length-1, 1)];
if (where.length) [finalStr appendFormat:@" %@", where];
flag = [_db executeUpdate:finalStr withArgumentsInArray:argumentsArr];
return flag;
}
-(NSArray *)YJ_findTable:(NSString *)tableName dicOrModel:(id)parameters whereFormat:(NSString *)format, ...{
va_list args;
va_start(args, format);
NSString *where = format?[[NSString alloc] initWithFormat:format locale:[NSLocale currentLocale] arguments:args]:format;
va_end(args);
NSMutableArray *resultMArr = [NSMutableArray arrayWithCapacity:0];
NSDictionary *dic;
NSMutableString *finalStr = [[NSMutableString alloc] initWithFormat:@"select * from %@ %@", tableName, where?where:@""];
NSArray *clomnArr = [self getColumnArr:tableName db:_db];
FMResultSet *set = [_db executeQuery:finalStr];
if ([parameters isKindOfClass:[NSDictionary class]]) {
dic = parameters;
while ([set next]) {
NSMutableDictionary *resultDic = [NSMutableDictionary dictionaryWithCapacity:0];
for (NSString *key in dic) {
if ([dic[key] isEqualToString:SQL_TEXT]) {
id value = [set stringForColumn:key];
if (value)
[resultDic setObject:value forKey:key];
} else if ([dic[key] isEqualToString:SQL_INTEGER]) {
[resultDic setObject:@([set longLongIntForColumn:key]) forKey:key];
} else if ([dic[key] isEqualToString:SQL_REAL]) {
[resultDic setObject:[NSNumber numberWithDouble:[set doubleForColumn:key]] forKey:key];
} else if ([dic[key] isEqualToString:SQL_BLOB]) {
id value = [set dataForColumn:key];
if (value)
[resultDic setObject:value forKey:key];
}
}
if (resultDic) [resultMArr addObject:resultDic];
}
}else {
Class CLS;
if ([parameters isKindOfClass:[NSString class]]) {
if (!NSClassFromString(parameters)) {
CLS = nil;
} else {
CLS = NSClassFromString(parameters);
}
} else if ([parameters isKindOfClass:[NSObject class]]) {
CLS = [parameters class];
} else {
CLS = parameters;
}
if (CLS) {
NSDictionary *propertyType = [self modelToDictionary:CLS excludePropertyName:nil];
while ([set next]) {
id model = CLS.new;
for (NSString *name in clomnArr) {
if ([propertyType[name] isEqualToString:SQL_TEXT]) {
id value = [set stringForColumn:name];
if (value)
[model setValue:value forKey:name];
} else if ([propertyType[name] isEqualToString:SQL_INTEGER]) {
[model setValue:@([set longLongIntForColumn:name]) forKey:name];
} else if ([propertyType[name] isEqualToString:SQL_REAL]) {
[model setValue:[NSNumber numberWithDouble:[set doubleForColumn:name]] forKey:name];
} else if ([propertyType[name] isEqualToString:SQL_BLOB]) {
id value = [set dataForColumn:name];
if (value)
[model setValue:value forKey:name];
}
}
[resultMArr addObject:model];
}
}
}
return resultMArr;
}
-(NSArray *)YJ_saveTable:(NSString *)tableName dicOrModelArray:(NSArray *)dicOrModelArray{
int errorIndex = 0;
NSMutableArray *resultMArr = [NSMutableArray arrayWithCapacity:0];
NSArray *columnArr = [self getColumnArr:tableName db:_db];
for (id parameters in dicOrModelArray) {
BOOL flag = [self insertTable:tableName dicOrModel:parameters columnArr:columnArr];
if (!flag) {
[resultMArr addObject:@(errorIndex)];
}
errorIndex++;
}
return resultMArr;
}
-(BOOL)YJ_deleteTable:(NSString *)tableName{
NSString *sqlstr = [NSString stringWithFormat:@"DROP TABLE %@", tableName];
if (![_db executeUpdate:sqlstr])
{
return NO;
}
return YES;
}
-(BOOL)YJ_deleteAllDataFromTable:(NSString *)tableName{
NSString *sqlstr = [NSString stringWithFormat:@"DELETE FROM %@", tableName];
if (![_db executeUpdate:sqlstr])
{
return NO;
}
return YES;
}
-(BOOL)YJ_isExistTable:(NSString *)tableName{
FMResultSet *set = [_db executeQuery:@"SELECT count(*) as 'count' FROM sqlite_master WHERE type ='table' and name = ?", tableName];
while ([set next])
{
NSInteger count = [set intForColumn:@"count"];
if (count == 0) {
return NO;
} else {
return YES;
}
}
return NO;
}
-(NSArray *)YJ_columnNameArray:(NSString *)tableName{
return [self getColumnArr:tableName db:_db];
}
-(int)YJ_tableItemCount:(NSString *)tableName{
NSString *sqlstr = [NSString stringWithFormat:@"SELECT count(*) as 'count' FROM %@", tableName];
FMResultSet *set = [_db executeQuery:sqlstr];
while ([set next])
{
return [set intForColumn:@"count"];
}
return 0;
}
- (void)close
{
[_db close];
}
- (void)open
{
[_db open];
}
-(NSInteger)lastInsertPrimaryKeyId:(NSString *)tableName{
NSString *sqlstr = [NSString stringWithFormat:@"SELECT * FROM %@ where pkid = (SELECT max(pkid) FROM %@)", tableName, tableName];
FMResultSet *set = [_db executeQuery:sqlstr];
while ([set next])
{
return [set longLongIntForColumn:@"pkid"];
}
return 0;
}
-(BOOL)YJ_alterTable:(NSString *)tableName dicOrModel:(id)parameters{
return [self YJ_alterTable:tableName dicOrModel:parameters excludeName:nil];
}
-(BOOL)YJ_alterTable:(NSString *)tableName dicOrModel:(id)parameters excludeName:(NSArray *)nameArr{
__block BOOL flag;
[self YJ_inTransaction:^(BOOL *rollback) {
if ([parameters isKindOfClass:[NSDictionary class]]) {
for (NSString *key in parameters) {
if ([nameArr containsObject:key]) {
continue;
}
flag = [_db executeUpdate:[NSString stringWithFormat:@"ALTER TABLE %@ ADD COLUMN %@ %@", tableName, key, parameters[key]]];
if (!flag) {
*rollback = YES;
return;
}
}
} else {
Class CLS;
if ([parameters isKindOfClass:[NSString class]]) {
if (!NSClassFromString(parameters)) {
CLS = nil;
} else {
CLS = NSClassFromString(parameters);
}
} else if ([parameters isKindOfClass:[NSObject class]]) {
CLS = [parameters class];
} else {
CLS = parameters;
}
NSDictionary *modelDic = [self modelToDictionary:CLS excludePropertyName:nameArr];
NSArray *columnArr = [self getColumnArr:tableName db:_db];
for (NSString *key in modelDic) {
if (![columnArr containsObject:key] && ![nameArr containsObject:key]) {
flag = [_db executeUpdate:[NSString stringWithFormat:@"ALTER TABLE %@ ADD COLUMN %@ %@", tableName, key, modelDic[key]]];
if (!flag) {
*rollback = YES;
return;
}
}
}
}
}];
return flag;
}
// ============================= 线程安全操作 ===============================
-(void)YJ_inDatabase:(void (^)(void))block{
[[self dbQueue] inDatabase:^(FMDatabase *db) {
block();
}];
}
-(void)YJ_inTransaction:(void (^)(BOOL *))block{
[[self dbQueue] inTransaction:^(FMDatabase *db, BOOL *rollback) {
block(rollback);
}];
}
@end
到了这里,基本所有用到FMDB的地方都能根据这些方法凑出来了,接下来会找更牛逼更方便的方法来实现存储功能,敬请期待。。。