本地做了一个浏览记录的缓存,在之前的版本中已经创建了一个对应的表,在新版本中对浏览记录进行了修改,所以得往已经存在的表中添加新的字段。
最开始以为只要在创建表的地方添加上新的字段便大功告成了。
NSString *sql = @"create table SearchStatistics (id integer primary key autoincrement, searchUserAgentId text, searchUUID text, keyword text)"; [_db executeUpdate:sql];
运行之后,发现添加的字段并没有生效,后来查看日志,发现新加的字段在插入的时候居然在表中找不到。
后来想了一下,因为之前本地这个表已经被创建了所以这个方法不会走了,于是便想到往已有的表中添加字段。
NSString *sql = @"alter table ReplaceSellList add keyword text"; [self.db executeUpdate:sql]
但是这样的话又会有一个问题,要是以后的版本还会要添加字段的话,那我势必写很多的sql来添加字段。于是乎想了一个办法,在本地创建一个 plist文件用来保存新增的字段,每次更新取表中的字段和plist文件中的字段作对比,取出新的字段生成对应的sql,最后更新表中字段。
class="cnblogs_code_copy">
#pragma mark 检查是否更新表字段
- (void)checkUpdateSearchTable
{
if ([self.db open]) {
if ([self.db tableExists:@"SearchStatistics"]) {
NSInteger lastVersion = [[[NSUserDefaults standardUserDefaults] objectForKey:SearchOldSqliteVersionKey] integerValue];
if (lastVersion < CURRENTSQLVERSION) {
[self updateSearchTable];
}
}
[self.db close];
}
}
#pragma mark 更新表字段
- (void)updateSearchTable
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"SearchStaticsField" ofType:@"plist"];
NSDictionary *newFiledDic = [[NSDictionary alloc]initWithContentsOfFile:path];
NSArray *allField = [self getColumnArr:@"SearchStatistics" db:self.db];
NSArray *newFilds = [self compareKeys:[newFiledDic allKeys] tableNames:allField]; //对比老表,获取需要更新的新字段
if (newFilds.count) {
NSMutableArray *sqls = [[NSMutableArray alloc]init];
for (NSString *key in newFilds) {
NSString *type = newFiledDic[key];
[sqls addObject:[NSString stringWithFormat:@"alter table SearchStatistics add %@ %@",key,type]];
}
//事务提交,更新表
[self.db beginTransaction]; // 调用之前打开db
BOOL isRollBack = NO;
@try {
for (int i = 0; i < sqls.count; i++) {
NSString *sql = sqls[i];
BOOL b = [self.db executeUpdate:sql];
if (!b) {
NSLog(@"第%d条sql语句执行失败", i);
}
}
}
@catch (NSException *exception) {
isRollBack = YES;
[self.db rollback];
}
@finally {
if (!isRollBack) {
if ([self.db commit]) {
[[NSUserDefaults standardUserDefaults] setInteger:CURRENTSQLVERSION forKey:SearchOldSqliteVersionKey];
}
}
}
}
[self.db close];
}
#pragma mark 获取表中所有字段
- (NSArray *)getColumnArr:(NSString *)tableName db:(FMDatabase *)db
{
NSMutableArray *mArr = [NSMutableArray arrayWithCapacity:0];
if ([self.db open]) {
FMResultSet *resultSet = [db getTableSchema:tableName];
while ([resultSet next]) {
[mArr addObject:[resultSet stringForColumn:@"name"]];
}
}
return mArr;
}
- (NSArray *)compareKeys:(NSArray *)keys tableNames:(NSArray *)tKeys
{
NSPredicate * filterPredicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)",tKeys];
//过滤数组
NSArray * reslutFilteredArray = [keys filteredArrayUsingPredicate:filterPredicate];
return reslutFilteredArray;
}
这样,每次有新的字段加入,只需要往plist文件中添加对应的字段,同时把数据库版本加一就行了。
各位要是有更好的方法,互相分享一下哈。