iOS数据库版本升级问题

作者: 城市之光 | 来源:发表于2016-07-05 22:59 被阅读2814次

项目中遇到一个数据库版本升级问题,最后还是解决了,现在来记录下这个坑。
iOS项目中有数据库方面的知识,之后的数据库表比较简单,为了实现产品经理给的需求,不得不和服务器那边协调通过增加数据表字段的方式来达到目的。之前,没有做数据库版本的记录问题,需求什么的都滚一边,产品太不专业了。现在我的需求是在不改变原来APP上的数据的基础上增加新的字段来实现消息推荐的已同意拒绝过期等状态。刚开始时,觉得这个问题不是很难,所以有点大意了,中间遇到很多坑,SQLite语法很严谨,所以遇到各种语法问题。还好,之前到随手记面试的时候,也遇到过这个面试题,当时没想太多,就说每次删掉旧的数据库DB,现在想想当时脑袋被门挤了吧。废话不多说,说多了也是泪啊。。
我的思路:要想确保之前的数据不丢失,应当在之前数据库表的基础上创建新的数据库表,哈哈,解决方案应运而生了。
1.判断数据库版本号和保存数据库版本号

NSString * const kdbManagerVersion = @"DBManagerVersion";

const static NSInteger DB_MANAGER_VER = 1;

// 升级操作

NSInteger ver = [[NSUserDefaults standardUserDefaults] integerForKey:kdbManagerVersion];
        
if (ver < DB_MANAGER_VER) {
     [self upgrade];
}

- (void)saveDBVersion {
    [[NSUserDefaults standardUserDefaults] setInteger:DB_MANAGER_VER forKey:kdbManagerVersion];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

2.数据库升级

- (void)upgrade {
     // 获取旧版本号
     NSInteger oldVersionNum = [[NSUserDefaults standardUserDefaults] integerForKey:kdbManagerVersion];
     if (DB_MANAGER_VER <= oldVersionNum) {
        return;
     }
     // 升级
     [self upgrade:oldVersionNum];

     // 保存新版本号
     [self saveDBVersion];
 }

 - (void)upgrade:(NSInteger)oldVersion {
      if (oldVersion >= DB_MANAGER_VER) {
          return;
      }
      switch (oldVersion) {
         case 0:
            [self upgradeFromOldToNew];
            break;
         case 1:
            [self upgradeFromOldToNew];
            break;
         case 2:
        
            break;
         default:
            break;
       }
       oldVersion++;

       // 判断是否需要升级
       [self upgrade:oldVersion];
  }

  - (void)upgradeFromOldToNew {
       // 执行版本1到版本2的更新
       [self changeDBData:_db];
  }

3.数据库升级的SQL语句操作

- (void)changeDBData:(FMDatabase *)db {
      [db open];
      // 变更数据库表为一个旧数据表
      NSString *sqlStr = [NSString stringWithFormat:@"ALTER TABLE %@ RENAME TO %@", self.tableName, [self.tableName stringByAppendingString:@"_Old"]];
     // 执行SQL语句操作
       [db executeUpdate:sqlStr];
     // 创建新的数据表
       NSString *executeStr = [NSString stringWithFormat:@"create table if not exists %@ (LocID integer primary key autoincrement not null,messageID text unique,Content text,TypeName text,SendTime text,CreateTime integer,Status integer,msgtype text,apply_id text,userid text,message_last_id text)",self.tableName];
      BOOL bRet = [db executeUpdate:executeStr];
      if (bRet) {
      // 从旧数据表把旧数据插入新的数据表中
          NSString *insertSql = [NSString stringWithFormat:@"INSERT INTO %@ SELECT * ,'','','' FROM %@", self.tableName, [self.tableName stringByAppendingString:@"_Old"]];
          [db executeUpdate:insertSql];
     }
    // 删除旧的数据表
     [db executeUpdate:[NSString stringWithFormat:@"DROP TABLE %@",      [self.tableName stringByAppendingString:@"_Old"]]];
     [db close];
 }

相关文章

网友评论

  • 杰森_Jason:问下,新表字段变了及增加了怎么迁移数据呢?
    强子ly:字段一般是不会变化的,增加就按照上面这种方式就行了
  • 困惑困惑困惑:为啥不在原来表的基础上增加新字段呢,这样太麻烦了,如何每次版本迭代都需要改数据库呢,或者极端一点,你现在的数据库的版本号是26,有的用户数据库的版本可能是0或者1很早的版本,呢
    强子ly:道理是一样的
  • 6a53b918bd3c:不要用递归 switch去掉break不就好了? Android就是这么升级数据库的
  • Crycil:数据迁移这里用事务处理更好一点
    城市之光:@Crycil 事务应该好点,失败可以回滚:+1:
  • li二彩:这里的版本号DB_MANAGER_VER 是不是要++呢?
    城市之光:@li二彩 这要看你数据库版本号来决定了

本文标题:iOS数据库版本升级问题

本文链接:https://www.haomeiwen.com/subject/egefjttx.html