• Realm数据持久化方案的简单介绍和使用(二)


     

    接上篇。。。

    4. 可空属性&默认值&忽略属性

    默认情况下, 属性值可空, 如果强制要求某个属性非空, 可以使用如下方法:

    遵循协议方法

    + (NSArray *)requiredProperties {

    return @[@"name"];

    }

    特点:如果再次赋值为nil, 则会抛出异常错误

    也可以设置默认值

    + (NSDictionary *)defaultPropertyValues {

    return @{@"name": @""};

    }

    忽略属性:不想存储的某些属性,其实现方法为

    + (NSArray *)ignoredProperties

    开发经验:

    可以借助忽略属性&只读属性 打造计算属性, 完成集合以及UIImage对象的存储与获取

    5. 通知

                Realm 实例将会在每次写入事务提交后,给其他线程上的 Realm 实例发送通知

                5.1. 获取 Realm 通知

                            token = [realm addNotificationBlock:^(NSString *notification, RLMRealm * realm) {

                                        // 接收到更改通知, 需要做的事情

                            }];

                5.2. 移除通知

                            [token stop];

                注意:必须持有返回的token

    6. Realm数据库

    实现方案

      不同的用户, 使用不同的数据库   

     + (void)setDefaultRealmForUser:(NSString *)username {
    
        RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
    
         // 使用默认的目录,但是使用用户名来替换默认的文件名
    
        config.fileURL= [[[config.fileURL URLByDeletingLastPathComponent]  URLByAppendingPathComponent:username]
    
                          URLByAppendingPathExtension:@"realm"]]];
    
         // 将这个配置应用到默认的 Realm 数据库当中
    
         [RLMRealmConfiguration setDefaultConfiguration:config];
    
     }

       只读方式打开数据库   

    RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
    
               
     // 获取需要打包文件的 URL 路径
    
     config.fileURL = [[NSBundle mainBundle] URLForResource:@"MyBundledData" withExtension:@"realm"];
    
     // 以只读模式打开文件,因为应用数据包并不可写
    
     config.readOnly = YES;
    
               
     // 通过配置打开 Realm 数据库
    
     RLMRealm *realm = [RLMRealm realmWithConfiguration:config error:nil];
    
     // 从打包的 Realm 数据库中读取某些数据
    
     RLMResults<Dog *> *dogs = [Dog objectsInRealm:realm where:@"age > 5"];

    数据库文件删除

        注意: 需要删除数据库文件以及辅助文件

        代码实战:

    NSFileManager *manager = [NSFileManager defaultManager];
    
    RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
    
    NSArray<NSURL *> *realmFileURLs = @[
    
      config.fileURL,
    
      [config.fileURL URLByAppendingPathExtension:@"lock"],
    
      [config.fileURL URLByAppendingPathExtension:@"log_a"],
    
      [config.fileURL URLByAppendingPathExtension:@"log_b"],
    
      [config.fileURL URLByAppendingPathExtension:@"note"]
    
    ];
    
    for (NSURL *URL in realmFileURLs) {
    
      NSError *error = nil;
    
      [manager removeItemAtURL:URL error:&error];
    
      if (error) {
    
        // 处理错误
    
      }
    
    }

    7. 数据库迁移

    适用于修改了数据模型的情况,这里分 数据结构迁移 以及 数据迁移 属性重命名 多版本增量式迁移 四个模块分别进行说明。 

    •   数据结构迁移
    // 在 [AppDelegate didFinishLaunchingWithOptions:] 中进行配置
    
    RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
    
    // 设置新的架构版本。这个版本号必须高于之前所用的版本号(如果您之前从未设置过架构版本,那么这个版本号设置为 0)
    
    config.schemaVersion = 1;
    
    // 设置闭包,这个闭包将会在打开低于上面所设置版本号的 Realm 数据库的时候被自动调用
    
    config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {
    
     
    
      // 目前我们还未进行数据迁移,因此 oldSchemaVersion == 0
    
      if (oldSchemaVersion < 1) {
    
    // 什么都不要做!Realm 会自行检测新增和需要移除的属性,然后自动更新硬盘上的数据库架构
    
    };
    
      }
    
    // 告诉 Realm 为默认的 Realm 数据库使用这个新的配置对象
    
    [RLMRealmConfiguration setDefaultConfiguration:config];
    
    // 现在我们已经告诉了 Realm 如何处理架构的变化,打开文件之后将会自动执行迁移
    
    [RLMRealm defaultRealm];
    •  数据迁移
    // enumerateObjects:block: 方法遍历了存储在 Realm 文件中的每一个“Person”对象
    
    [migration enumerateObjects:Person.className block:^(RLMObject *oldObject, RLMObject *newObject) {
    
    // 将名字进行合并,存放在 fullName 域中
    
          newObject[@"fullName"] = [NSString stringWithFormat:@"%@ %@", oldObject[@"firstName"], oldObject[@"lastName"]];
                                        
        }];
    • 属性重命名

            [migration renamePropertyForClass:Person.className oldName:@"yearsSinceBirth" newName:版本0

      

    • 多版本增量式迁移

      假设有如下3个数据库版本:

    
    
    版本0

    //
    v0 @interface Person : RLMObject @property NSString *firstName; @property NSString *lastName; @property int age; @end 版本1 // v1 @interface Person : RLMObject @property NSString *fullName; // 新属性 @property int age; @end 版本2 // v2 @interface Person : RLMObject @property NSString *fullName; @property NSString *email; // 新属性 @property int age; @end

       迁移核心代码

    if (oldSchemaVersion < 1) { 
    
          newObject[@"fullName"] = [NSString stringWithFormat:@"%@ %@",
    
    oldObject[@"firstName"],  oldObject[@"lastName"]];
    
    }
    
    // 只有当 Realm 数据库的架构版本为 0 的时候,才添加 “fullName” 属性
    
     [migration enumerateObjects:Person.className
    
    block:^(RLMObject *oldObject, RLMObject *newObject) {
    
             if (oldSchemaVersion < 2) {
    
    newObject[@"email"] = @"";
    
      }
    }];
  • 相关阅读:
    关于垂直居中
    linux 前后台程序切换
    mac 下jetbrains IDE系列IDE主题
    mac 安装命令行开发者工具
    python 安装MySQLdb mysql_config not fount
    error: command 'cc' failed with exit status 1
    sqllite 入门
    jieba分词
    zookeeper 故障重连机制
    深入学习 celery
  • 原文地址:https://www.cnblogs.com/imsz/p/6664020.html
Copyright © 2020-2023  润新知