Realm的一对多配置以及版本兼容

前言:本篇博客将介绍Realm的一些高级用法,基本使用在这里

一、配置一对多关系

 1 //
 2 //  Teacher.h
 3 
 4 #import <Realm/Realm.h>
 5 #import "Student.h"
 6 
 7 @interface Teacher : RLMObject
 8 
 9 @property NSInteger _ID;
10 @property NSString *name;
11 @property NSInteger age;
12 @property NSString *sex;
13 @property RLMArray<Student *><Student> *students;
14 
15 @end
 1 //  Student.h
 2 
 3 #import <Realm/Realm.h>
 4 
 5 @interface Student : RLMObject
 6 
 7 @property NSString *name;
 8 @property(readonly) RLMLinkingObjects *teacher;
 9 
10 @end
11 
12 RLM_ARRAY_TYPE(Student)

 

解析:1、假设现在Teacher为一的这一端多即是指Student(PS:虽然一个学生也可以对应多个老师,本例只是说明问题请勿纠结细节)

2、在多的这个属性上用RLMArray修饰之前必须在多的这一端即Student中添加一个宏RLM_ARRAY_TYPE

插入数据

 1 RLMRealm *realm = [RLMRealm defaultRealm];
 2         [realm transactionWithBlock:^{
 3             Teacher *teacherWan = [[Teacher alloc]init];
 4             teacherWan._ID = _IDNumber;
 5             teacherWan.name = @"小明";
 6             teacherWan.age = 13;
 7             teacherWan.sex = @"male";
 8     
 9             Student *stu1 = [[Student alloc]init];
10             stu1.name = @"旺财";
11     
12             Student *stu2 = [[Student alloc]init];
13             stu2.name = @"来福";
14             [teacherWan.students addObject:stu1];
15             [teacherWan.students addObject:stu2];
16             [realm addObject:teacherWan];
17             
18             [realm commitWriteTransaction];
19 }];

查询数据

二、反向链接

 1 //  Student.m
 2 
 3 #import "Student.h"
 4 #import "Teacher.h"
 5 
 6 @implementation Student
 7 
 8 //反向链接
 9 + (NSDictionary *)linkingObjectsProperties {
10     return @{
11              @"teacher": [RLMPropertyDescriptor descriptorWithClass:Teacher.class propertyName:@"students"],
12              };
13 }
14 
15 @end

解析:1、借助链接对象属性,您可以通过指定的属性来获取所有链接到指定对象的对象。例如,一个 Teacher 对象可以拥有一个名为 students 的链接对象属性,这个属性中包含了某些 Student 对象,而这些 Student 对象在其 teacher 属性中包含了这一个确定的 Teacher 对象。您可以将 teacher 属性设置为 RLMLinkingObjects 类型,然后重写 +[RLMObject linkingObjectsProperties] 来指明关系,说明 student 中包含了 Teacher 模型对象。(引用官网解释)

2、其实就是可以通过一的这一端可以知道多的有哪些,从多的这一端可以知道与其关联的一是什么。(个人理解)

三、版本兼容

PS: 一个应用难免要进行版本升级,而版本升级中往往需要将对原有对象的结构进行更改,可能是删除了一个表或者是在一张表中添加了一个字段又或者是把一个表的字段名更改了。当版本更新时,我们又需要保留用户在上一个版本中保存的一些信息,如果我们不做版本兼容,那就意味着原有数据将会丢失。

1、在AppDelegate中添加以下代码

 1 RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];
 2     config.schemaVersion = 4;
 3     NSLog(@"%llu", config.schemaVersion);
 4     config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {
 5         if (oldSchemaVersion < 2){
 6             NSLog(@"-------%llu", oldSchemaVersion);
 7             [migration renamePropertyForClass:Person.className oldName:@"name" newName:@"nickName"];
 8         }
 9         
10         if (oldSchemaVersion < 3){
11             NSLog(@"-------%llu", oldSchemaVersion);
12             [migration deleteDataForClassName:@"Human"];
13         }
14         
15         if (oldSchemaVersion < 4){
16             NSLog(@"-------%llu", oldSchemaVersion);
17             [migration deleteDataForClassName:@"Cat"];
18         }
19     };
20     [RLMRealmConfiguration setDefaultConfiguration:config];
21     [RLMRealm defaultRealm];

解析:1、记录数据仓库的版本号config.schemaVersion 默认从0开始,每一次升级的number必须比上一次大

2、如果需要修改一个表的字段,只需先修改对应对象的属性名,然后再在版本兼容中调用migration 的renamePropertyForClass方法

3、如需在一张表中添加或删除一个字段,只需要在对应的对象中添加或删除属性即可,在应用启动时会自动添加或删除

4、如需添加一张表,也只需要创建一个新的RLMObject对象子类即可

5、如需删除一张表,先将该对象删除,然后同理在版本兼容中调用migration 的deleteDataForClassName方法

posted @ 2017-06-20 16:23  艾达  阅读(1544)  评论(0编辑  收藏  举报