持久化方案-Realm(三)

246 阅读2分钟

Realm数据库配置

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

  RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration]; 
   // 使用默认的目录,但是使用用户名来替换默认的文件名
     config.fileURL = [[[config.fileURL URLByDeletingLastPathComponent]URLByAppendingPathComponent:@"userName"]URLByAppendingPathExtension:@"realm"];
       [RLMRealmConfiguration setDefaultConfiguration:config];
       

只读方式打开数据库

RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
config.fileURL = [[NSBundle mainBundle] URLForResource:@"MyBundledData" withExtension:@"realm"];
// 以只读模式打开文件,因为应用数据包并不可写
config.readOnly = YES;
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) {
    // 处理错误
  }
}

数据库迁移

数据结构迁移


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:@"age"];

多版本增量式迁移


迁移核心代码
	// enumerateObjects:block: 遍历了存储在 Realm 文件中的每一个“Person”对象
	[migration enumerateObjects:Person.className block:^(RLMObject *oldObject, RLMObject *newObject) {
// 只有当 Realm 数据库的架构版本为 0 的时候,才添加 “fullName” 属性
	    if (oldSchemaVersion < 1) {
	      newObject[@"fullName"] = [NSString stringWithFormat:@"%@ %@", oldObject[@"firstName"],oldObject[@"lastName"]];
	    }
// 只有当 Realm 数据库的架构版本为 0 或者 1 的时候,才添加“email”属性
	    if (oldSchemaVersion < 2) {
	      newObject[@"email"] = @"";
	    }
	  }];