一、数据库的升级
FMDB的数据迁移用FMDBMigrationManager这个工具类,FMDBMigrationManager 是与FMDB结合使用的一个第三方类库,可以记录数据库版本号并对数据库进行数据库升级等操作。
1、FMDB数据库升级有二种方式:
第一种、添加文件的方式进行记录版本和升级操作,先关联FMDBMigrationManager,再创建数据库升级文件,最后升级。
第二种、使用自定义类的形式进行迁移。先关联FMDBMigrationManager,再创建自定义类,并且遵循FMDBMigrationManager协议,最后把创建的自定义的类型加入到FMDBMigrationManager中,升级。
使用FMDBMigrationManager去
注意:上述两种数据库的升级方式都需要自己写sql语句。这就意味着,你需要熟练使用sql命令。
第一种:数据库升级的步骤:

1、集成FMDBMigrationManager
可以使用cocoapods或者手动集成
2、将要升级的的数据库和FMDBMigrationManager关联起来
注意:oldPath 要升级数据库的路径
执行了上面的代码以后,会发现多了一个 schema_migrations的表。
这个表是用来存储版本号的,现在表中的版本号(version)为0 ,rowid是升级文件“_”前面的数字。

注意:
下面这句代码是升级数据库的主要代码
UINT64_MAX 表示升级到最高版本
我们说的升级文件就是sql文件,里面写的是数据库操作的sql语句.
sql文件的文件名的格式都是是固定的 (数字)_(描述性语言).sql,最前面的数字就是版本号,可以使用1,2,3,4,5……升级,保持单调递增即可;也可以使用时间戳,官方建议使用时间戳,sql文件内写入要对数据库做的操作的sql语句。
注意:
可以命令行创建相应的sql文件,XXXXXXXXXXXXX是描述性语言。
$ touch "`ruby -e "puts Time.now.strftime('%Y%m%d%H%M%S%3N').to_i"`"_XXXXXXXXXXXXX.sql


然后把sql文件拖入我们的工程中

这时FMDBMigrationManager将会根据创建时给入的NSBundle自行寻找sql文件,进行版本号对比操作。添加sql文件之后,重启该项目,再运行一次升级代码,这时查看数据库,这时你就会发现刚刚在sql文件中创建的Student表了。
如果你想在Student表中添加一个新的字段,可以再添加一个sql文件,在里面写上你需要执行的sql命令,再把这个文件拖入工程中。重新启动项目,这时,你就会发现你的Student表中多了一个number字段。

现在存储的版本号是2了。如果你想升级成3,只要创建3_XXXXX.sql文件,在sql文件中写相应操作的sql语句就可以了。4、5、6等以此类推,也是使用时间戳来代替。
fmdb的升级方式和coredata的升级方式有点类似,fmdb是创建相应版本的sql文件,coredata是创建相应版本的XXXX.xcdatamodeld。
注意:其实升级的主要方式是逐级升级,如果当前版本是2,现在要升级到版本5,这样他会先升级到3,再从3升级到4,最后在升级到最终的版本5.

创建一个类,需要遵循FMDBMigrating协议
然后将自定义的对象添加进入FMDBMigrationManager类里面,进行升级操作
注意:
1、这里不需要创建很多的自定义类来升级数据库,只需要创建一个自定义类来实现数据库的升级。通过不同的自定义对象,来实现数据库的升级。比如下面的代码中定义了migrationOne和migrationTwo对象来实现了2个版本的升级。如果需要升级版本3,你需要在定义一个migrationThree对象,version传递3就可以了。
2、migrationOne和migrationTwo对象中的版本号(version)需要递增。executeUpdateArray这个数组可以传递多个升级语句。Name是每个版本的升级描述。
一个对象可以执行多个sql语句:
二、遇到的问题
1、FMDB迁移数据的问题
a、一定要明确每个版本的版本号,不然会造成数据升级失败,程序奔溃
FMDB的数据迁移用FMDBMigrationManager这个工具类,FMDBMigrationManager 是与FMDB结合使用的一个第三方类库,可以记录数据库版本号并对数据库进行数据库升级等操作。
1、FMDB数据库升级有二种方式:
第一种、添加文件的方式进行记录版本和升级操作,先关联FMDBMigrationManager,再创建数据库升级文件,最后升级。
第二种、使用自定义类的形式进行迁移。先关联FMDBMigrationManager,再创建自定义类,并且遵循FMDBMigrationManager协议,最后把创建的自定义的类型加入到FMDBMigrationManager中,升级。
使用FMDBMigrationManager去
注意:上述两种数据库的升级方式都需要自己写sql语句。这就意味着,你需要熟练使用sql命令。
第一种:数据库升级的步骤:

1、集成FMDBMigrationManager
可以使用cocoapods或者手动集成
2、将要升级的的数据库和FMDBMigrationManager关联起来
注意:oldPath 要升级数据库的路径
FMDBMigrationManager * manager=[FMDBMigrationManager managerWithDatabaseAtPath:oldPath migrationsBundle:[NSBundle mainBundle]];
BOOL resultState=NO;
NSError * error=nil;
if (!manager.hasMigrationsTable) {
resultState=[manager createMigrationsTable:&;error];
}
执行了上面的代码以后,会发现多了一个 schema_migrations的表。
这个表是用来存储版本号的,现在表中的版本号(version)为0 ,rowid是升级文件“_”前面的数字。

注意:
下面这句代码是升级数据库的主要代码
UINT64_MAX 表示升级到最高版本
resultState=[manager migrateDatabaseToVersion:UINT64_MAX progress:nil error:&;error]; 3、创建升级文件(sql文件)我们说的升级文件就是sql文件,里面写的是数据库操作的sql语句.
sql文件的文件名的格式都是是固定的 (数字)_(描述性语言).sql,最前面的数字就是版本号,可以使用1,2,3,4,5……升级,保持单调递增即可;也可以使用时间戳,官方建议使用时间戳,sql文件内写入要对数据库做的操作的sql语句。
注意:
可以命令行创建相应的sql文件,XXXXXXXXXXXXX是描述性语言。
$ touch "`ruby -e "puts Time.now.strftime('%Y%m%d%H%M%S%3N').to_i"`"_XXXXXXXXXXXXX.sql


然后把sql文件拖入我们的工程中

这时FMDBMigrationManager将会根据创建时给入的NSBundle自行寻找sql文件,进行版本号对比操作。添加sql文件之后,重启该项目,再运行一次升级代码,这时查看数据库,这时你就会发现刚刚在sql文件中创建的Student表了。
如果你想在Student表中添加一个新的字段,可以再添加一个sql文件,在里面写上你需要执行的sql命令,再把这个文件拖入工程中。重新启动项目,这时,你就会发现你的Student表中多了一个number字段。

现在存储的版本号是2了。如果你想升级成3,只要创建3_XXXXX.sql文件,在sql文件中写相应操作的sql语句就可以了。4、5、6等以此类推,也是使用时间戳来代替。
fmdb的升级方式和coredata的升级方式有点类似,fmdb是创建相应版本的sql文件,coredata是创建相应版本的XXXX.xcdatamodeld。
注意:其实升级的主要方式是逐级升级,如果当前版本是2,现在要升级到版本5,这样他会先升级到3,再从3升级到4,最后在升级到最终的版本5.
schema_migrations表中记录的是你已经迁移成功的数据库版本和对应的sql文件


创建一个类,需要遵循FMDBMigrating协议
@interface StudentMigration : NSObject<FMDBMigrating>
@property (nonatomic, readonly) NSString *name;
@property (nonatomic, readonly) uint64_t version;
- (instancetype)initWithName:(NSString *)name version:(uint64_t)version executeUpdateArray:(NSArray *)updateArray;
- (BOOL)studentrMigrateDatabase:(FMDatabase *)database error:(out NSError *__autoreleasing *)error;
@end@interface StudentMigration()
@property(nonatomic,copy)NSString * mName;
@property(nonatomic,assign)uint64_t mVersion;
@property(nonatomic,strong)NSArray * mUpdateArray;
@end
@implementation StudentMigration
- (instancetype)initWithName:(NSString *)name version:(uint64_t)version executeUpdateArray:(NSArray *)updateArray
{
if (self=[super init]) {
_mName=name;
_mVersion=version;
_mUpdateArray=updateArray;
}
return self;
}
- (NSString *)name
{
return _mName;
}
- (uint64_t)version
{
return _mVersion;
}
- (BOOL)studentMigrateDatabase:(FMDatabase *)database error:(out NSError *__autoreleasing *)error
{
for(NSString * updateStr in _mUpdateArray)
{
[database executeUpdate:updateStr];
}
return YES;
}
@end
然后将自定义的对象添加进入FMDBMigrationManager类里面,进行升级操作
注意:
1、这里不需要创建很多的自定义类来升级数据库,只需要创建一个自定义类来实现数据库的升级。通过不同的自定义对象,来实现数据库的升级。比如下面的代码中定义了migrationOne和migrationTwo对象来实现了2个版本的升级。如果需要升级版本3,你需要在定义一个migrationThree对象,version传递3就可以了。
2、migrationOne和migrationTwo对象中的版本号(version)需要递增。executeUpdateArray这个数组可以传递多个升级语句。Name是每个版本的升级描述。
//oldPath是要升级的数据库的地址
NSString *oldPath = KFMDBName;
FMDBMigrationManager * manager = [FMDBMigrationManager managerWithDatabaseAtPath:oldPath migrationsBundle:[NSBundle mainBundle]];
StudentMigration * migrationOne=[[UserMigration alloc]initWithName:@"新创建Student表" version:1 executeUpdateArray:@[@"create table Student(name text,age integer,nick text)"]];
[manager addMigration:migrationOne];
StudentMigration * migrationTwo=[[UserMigration alloc]initWithName:@"Student表新增number" version:2 executeUpdateArray:@[@"alter table Student add number text"]];
[manager addMigration:migrationTwo];
BOOL resultState=NO;
NSError * error=nil;
if (!manager.hasMigrationsTable) {
resultState=[manager createMigrationsTable:&error];
}
//UINT64_MAX 表示升级到最高版本
resultState=[manager migrateDatabaseToVersion:UINT64_MAX progress:nil error:&error];一个对象可以执行多个sql语句:
//一个对象执行升级多个SQL语句
StudentMigration * migrationThree=[[UserMigration alloc]initWithName:@"新创建teacher表,Student表新增Sex" version:3 executeUpdateArray:@[@"alter table Student add Sex text",@"create table teacher(name text,age integer,nick text)"]];
[manager addMigration:migrationThree];
二、遇到的问题
1、FMDB迁移数据的问题
a、一定要明确每个版本的版本号,不然会造成数据升级失败,程序奔溃
比如:之前升级了版本1、2、4、5版本了,这时候你的版本号添加的版本号是3,版本3中添加的一个字段number字段。可是,你的版本号不是逐级递增的,这样就会导致版本3迁移失败,还是原来的版本5,其他类中在使用number这个字段发现该字段并不存在。
三、参考文件
FMDB数据库的迁移 ------https://www.jianshu.com/p/736b00b3a1e1
FMDBMigrationManager下载,使用说明 https://github.com/layerhq/FMDBMigrationManager/blob/master/README.md
四、结束语
本文是介绍了FMDB数据库二种升级的方式,如果有侵权或者写的不好的地方,请留言,我会及时修改。谢谢大家。
博客讲述了在FMDB数据库中遇到的版本升级问题,强调了版本号递增的重要性。当非顺序添加版本,如从1、2、4、5跳到3时,由于缺失中间的迁移步骤,可能导致字段添加失败。文章提到了schema_migrations表记录已迁移的版本和对应SQL,并提供了FMDB数据库迁移的相关参考资源。
325

被折叠的 条评论
为什么被折叠?



