前一篇文章写了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 <Foundation/Foundation.h> @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 <objc/runtime.h> // 数据库中常见的几种类型 #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的地方都能根据这些方法凑出来了,接下来会找更牛逼更方便的方法来实现存储功能,敬请期待。。。