FMDB数据迁移

公司项目中,一般都需要做数据持久化,我们使用的是FMDB操作Sqlite,正常使用过程中,没有什么问题,但是一旦需求改了,数据结构发生变化,需要增加字段的时候,就必须要考虑数据迁移的问题,原来用了种很不好的处理方式,每次版本升级,就删除本地数据库,这种方式很不友好,于是考虑如何优化数据库的迁移操作.
因为项目用的是FMDB,所以数据迁移就用这个FMDBMigrationManager工具类,FMDBMigrationManager 是与FMDB结合使用的一个第三方,可以记录数据库版本号并对数据库进行数据库升级等操作。

操作步骤
1.新建一个Xcode的项目,并集成FMDB和FMDBMigrationManager(建议使用cocoapods,这里不再多说.)
2.创建一个数据库,这里是我们将要进行升级操作的数据库。

- (void)testCreatSqlite{
    NSString *filePath = [self getPath];
    FMDatabase * db=[FMDatabase databaseWithPath:filePath];
    _db=db;
    if ([_db open]) {
    //创建一个名为Student的表 
    BOOL result = [_db executeUpdate:@"CREATE TABLE  if not exists Book (id integer primary key autoincrement, bookNumber integer, bookName text, authorID integer, pressName text);"];
  if (result) {
       NSLog(@"创表成功");
  }else{
       NSLog(@"创表失败");
  }
  //存入十个水浒传
 for (int i=0; i<10; i++) {
            NSString *bookName = [NSString stringWithFormat:@"水浒传%d",i+1];
            NSString *bookNumber = [NSString stringWithFormat:@"数量%d",i+1];
            [_db executeUpdate:@"INSERT INTO book (bookName,bookNumber) VALUES (?,?)",bookName,bookNumber];
        }
    }
    [_db close];
}

创建成果后数据结构如下所示:

1672235-21f98f51b1961443.png
1-1.png

3.将要进行升级操作的数据库与 FMDBMigrationManager关联起来

//[self getPath]是数据库路径
    FMDBMigrationManager * manager=[FMDBMigrationManager managerWithDatabaseAtPath:[self getPath] migrationsBundle:[NSBundle mainBundle]];

4.创建迁移表

    BOOL resultState=NO;
    NSError * error=nil;
    if (!manager.hasMigrationsTable) {
        resultState=[manager createMigrationsTable:&error];
    }
   resultState=[manager migrateDatabaseToVersion:UINT64_MAX progress:nil error:&error];

控制台输出:

2017-08-25 11:28:19.358 FMDBMigrationManagerDemo[5508:149471] Origin Version: 0
2017-08-25 11:28:19.358 FMDBMigrationManagerDemo[5508:149471] Current version: 0
2017-08-25 11:28:19.359 FMDBMigrationManagerDemo[5508:149471] All migrations: (
    "<Migration: 0x608000038620>"
)
2017-08-25 11:28:19.359 FMDBMigrationManagerDemo[5508:149471] Applied versions: (
    0
)
2017-08-25 11:28:51.474 FMDBMigrationManagerDemo[5508:149471] Pending versions: (
)

执行完该语句,再去查看数据库,会发现多了一个表 schema_migrations

1672235-6aa997dca31f1608.png
1-2.png

这个表就是用来存储版本号的,目前表中的版本号(version)为0。

5.使用自定义类的形式升级,定义一个新的类:Migration,遵循FMDBMigrating协议

1672235-829efceed7662b33.png
1-5.png

1672235-ee7977596318b462.png
1-6.png

使用方法也很简单,将自定义类对象添加进manager即可。

    Migration * migration_2=[[Migration alloc]initWithName:@"Book" andVersion:2 andExecuteUpdateArray:@[@"alter table Book add book_email text"]];//给User表添加email字段
    Migration * migration_3=[[Migration alloc]initWithName:@"Book" andVersion:3 andExecuteUpdateArray:@[@"alter table Book add book_address text"]];
    [manager addMigration:migration_2];
    [manager addMigration:migration_3];

6.加入一个新增数据库的字段(项目中常用的升级操作就是增加数据库字段)
完整的新增数据库字段的代码

- (void)testupdatePrivateMsg{
    NSString *filePath = [self getPath];
    NSLog(@"-----filePath:%@",filePath);
    FMDBMigrationManager * manager=[FMDBMigrationManager managerWithDatabaseAtPath:filePath migrationsBundle:[NSBundle mainBundle]];
  Migration * migration_1=[[Migration alloc]initWithName:@"Book" andVersion:1 andExecuteUpdateArray:@[@"alter table Book add book_email text"]];//给User表添加email字段
   
    Migration * migration_2=[[Migration alloc]initWithName:@"Book" andVersion:2 andExecuteUpdateArray:@[@"alter table Book add book_address text"]];
    [manager addMigration:migration_1];
    [manager addMigration:migration_2];
    
    BOOL resultState=NO;
    NSError * error=nil;
    if (!manager.hasMigrationsTable) {
        resultState=[manager createMigrationsTable:&error];
    }
   resultState=[manager migrateDatabaseToVersion:UINT64_MAX progress:nil error:&error];
}

执行完代码后,查看数据库,发现已经多了一个book_email和book_address的字段了.

1672235-c890d995e6f384e4.png
1-3.png

数据库中存储的版本号也发生相应的改变了

1672235-e71932350d1fc7fe.png
1-4.png

如果以后还想升级,再加入一个新的自定义对象即可, 注意!!! 版本号一定要保持递增.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值