zoukankan      html  css  js  c++  java
  • FMDB数据库升级

    FMDBMigrationManager 是与FMDB结合使用的一个第三方,可以记录数据库版本号并对数据库进行数据库升级等操作。
    首先要集成FMDB和FMDBMigrationManager,建议使用cocoapods,这里不再多说。
    根据官方文档的解释,有两种方法实现升级,我们一个一个的解释。
    先说第一种,添加文件的方式进行记录版本和升级操作,新建一个空白的项目,并创建一个数据库,也就是我们将要进行升级操作的数据库。
    将数据库与我们的FMDBMigrationManager关联起来

    FMDBMigrationManager * manager=[FMDBMigrationManager managerWithDatabaseAtPath:DBPath migrationsBundle:[NSBundle mainBundle]];
    //DBPath是要升级的数据库的地址 
    // [NSBundle mainBundle]是保存数据库升级文件的位置 根据自己放文件的位置定 升级文件是什么下面会说

    下面创建版本号表,这个表会保存在我们的数据库中,进行数据库版本号的记录,并将我们的数据库升级到最高的版本。

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

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

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

    下面是最重要的升级语句

    BOOL resultState=NO;
      resultState=[manager migrateDatabaseToVersion:UINT64_MAX progress:nil error:&error];
    //UINT64_MAX 表示升级到最高版本

    整体的升级函数就是

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

    此时还没有添加升级文件,所以执行完这段代码数据库并没有什么变化,下面添加升级文件。
    所谓升级文件,就是一些sql文件,在里面写入一些对数据库操作的语句

    文件名的格式是固定的 (数字)_(描述性语言).sql,前面的数字就是所谓的版本号,官方建议使用时间戳,也可以使用1,2,3,4,5……升级,保持单调递增即可。
    文件内写入要对数据库做的操作

    然后将文件拖入工程

    FMDBMigrationManager 将会根据创建时给入的NSBundle自行寻找sql文件,对比版本号进行操作。添加sql文件之后,重启项目,再运行一次升级代码,查看数据库

    发现新增了一个User表,再加入一个新增数据库字段的文件(工程中常用的升级操作就是增加数据库字段)

    2_AddEmail.sql 的内容

    重启项目运行升级代码,查看数据库

    发现email已经添加进来了 

     

    存储的版本号也已经记录到2了,以后还想升级的话,再向项目中添加 3_*.sql 文件就好了。

    下面使用第二种方法进行升级,使用自定义类的形式。
    第一种方法,每次升级都要建立一个文件,而且大多数时候,文件里面只写一句话,感情上会难以接受,因此我们介绍一种较为简洁的方式。
    首先定义一个新的类:Migration

    //
    //  Migration.h
    //  FMDB
    //
    //  Created by czc on 16/5/23.
    //  Copyright © 2016年 alan. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import "FMDBMigrationManager.h"
    
    @interface Migration : NSObject<FMDBMigrating>
    
    @property (nonatomic, readonly) NSString *name;
    @property (nonatomic, readonly) uint64_t version;
    - (BOOL)migrateDatabase:(FMDatabase *)database error:(out NSError *__autoreleasing *)error;
    
    
    @end

    遵循FMDBMigrating协议,与第一种拖入文件的方式相同,name是升级描述,version是版本号,最后一个方法里面,进行操作。
    由于name和version都是只读的,因此我们要自定义一个init方法,传入描述 版本号和升级语句,升级语句最好用数组的方式传入,因为可能有多个升级语句。

    #import <Foundation/Foundation.h>
    #import "FMDBMigrationManager.h"
    
    @interface Migration : NSObject<FMDBMigrating>
    
    - (instancetype)initWithName:(NSString *)name andVersion:(uint64_t)version andExecuteUpdateArray:(NSArray *)updateArray;//自定义方法
    
    @property (nonatomic, readonly) NSString *name;
    @property (nonatomic, readonly) uint64_t version;
    - (BOOL)migrateDatabase:(FMDatabase *)database error:(out NSError *__autoreleasing *)error;
    
    
    @end
    #import "Migration.h"
    
    @interface Migration()
    
    @property(nonatomic,copy)NSString * myName;
    @property(nonatomic,assign)uint64_t myVersion;
    @property(nonatomic,strong)NSArray * updateArray;
    @end
    
    @implementation Migration
    
    - (instancetype)initWithName:(NSString *)name andVersion:(uint64_t)version andExecuteUpdateArray:(NSArray *)updateArray
    {
        if (self=[super init]) {
            _myName=name;
            _myVersion=version;
            _updateArray=updateArray;
        }
        return self;
    }
    
    - (NSString *)name
    {
        return _myName;
    }
    
    - (uint64_t)version
    {
        return _myVersion;
    }
    
    - (BOOL)migrateDatabase:(FMDatabase *)database error:(out NSError *__autoreleasing *)error
    {
        for(NSString * updateStr in _updateArray)
        {
            [database executeUpdate:updateStr];
        }
        return YES;
    }
    
    @end

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

    FMDBMigrationManager * manager=[FMDBMigrationManager managerWithDatabaseAtPath:DBPath migrationsBundle:[NSBundle mainBundle]];
    
        Migration * migration_1=[[Migration alloc]initWithName:@"新增USer表" andVersion:1 andExecuteUpdateArray:@[@"create table User(name text,age integer)"]];
        Migration * migration_2=[[Migration alloc]initWithName:@"USer表新增字段email" andVersion:2 andExecuteUpdateArray:@[@"alter table User add email 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];

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

     FMDBMigrationManager * manager=[FMDBMigrationManager managerWithDatabaseAtPath:DBPath migrationsBundle:[NSBundle mainBundle]];
    
        Migration * migration_1=[[Migration alloc]initWithName:@"新增USer表" andVersion:1 andExecuteUpdateArray:@[@"create table User(name text,age integer)"]];
        Migration * migration_2=[[Migration alloc]initWithName:@"USer表新增字段email" andVersion:2 andExecuteUpdateArray:@[@"alter table User add email text"]];
        Migration * migration_3=[[Migration alloc]initWithName:@"USer表新增字段address" andVersion:3 andExecuteUpdateArray:@[@"alter table User add address text"]];
        [manager addMigration:migration_1];
        [manager addMigration:migration_2];
        [manager addMigration:migration_3];
    
        BOOL resultState=NO;
        NSError * error=nil;
        if (!manager.hasMigrationsTable) {
            resultState=[manager createMigrationsTable:&error];
        }
    
        resultState=[manager migrateDatabaseToVersion:UINT64_MAX progress:nil error:&error];
  • 相关阅读:
    Atitit.随时间变色特效 ---包厢管理系统的规划
    Atitit.request http乱码的设计防止 检测与解决最近实践p825 attilax总结.doc
    Atitit.request http乱码的设计防止 检测与解决最近实践p825 attilax总结.doc
    atitit.薄伽梵歌overview  attilax 读后感
    Atitit。 《吠陀》 《梨俱吠陀》overview 经读后感  是印度上古时期一些文献的总称
    Atitit。 《吠陀》 《梨俱吠陀》overview 经读后感  是印度上古时期一些文献的总称
    atitit.薄伽梵歌overview  attilax 读后感
    Atitit 《摩奴法典》overivew 读后感 不是由国王 颁布的,而是 僧侣编制
    Atitit 《摩奴法典》overivew 读后感 不是由国王 颁布的,而是 僧侣编制
    Atitit.执行cli cmd的原理与调试
  • 原文地址:https://www.cnblogs.com/czc-wjm/p/5873237.html
Copyright © 2011-2022 走看看