CoreData 从入门到精通(三)关联表的创建

上篇博客中讲了 CoreData 里增删改查的使用,学到这里已经可以应对简单的数据存储需求了。但是当数据模型复杂起来时,例如你的模型类中除了要存储 CoreData 里支持的数据类型外,还有一些自定义的数据类型,这个时候只靠单一的模型结构就没办法来满足这种需求了,于是我们就需要使用关联表结构,也就是我们这次要讲的内容。

简介

多表关联,相信接触过 SQL 数据库的朋友都不陌生,就是指可以在一张表的数据中可以引用另外一张表里的数据。QQ 里的好友关系,微博里的用户和微博条目之间都用到了多表之间的关联。同样的,在 CoreData 里,也可以实现这样的功能,而且 CoreData 比起传统的 SQL 数据库来,更加简单。

创建关联表

CoreData 里的多表关联,是通过 Entity 实体中的 Relationships 来实现的:


Relationships-w600

上篇文章中,我们已经创建好了一个 Student 实体,现在我们需要再创建两个实体,分别是 和 Course 分别代表班级和课程。首先来创建出这两张表。
Clazz 班级表:


Clazz-w600

Course 课程表:


Course-w600

表创建好后,我们来为这三张表建立关联关系,它们之间的关系是这样的:Student 里有一个 studentClass 字段代表学生所属的班级,一个 studentCourses 字段代表学生在学的所有课程;

Clazz 里有一个 classStudents 字段代表班级里所有的学生;Course 里有一个 courseStudents 代表学习这门课程的所有学生。可以看出来,这几个字段都是彼此关联的关系。根据上面说的,我们需要用 relationships 来创建这些关联的字段。
首先来创建 Student 里的两个关系:


studentClass-w600

先看 studentClass 字段,在 1 中,Destination 属性指的是和这个 字段建立关联的实体的名字,这里可以选择 DataModel 中的其他实体,也可以是当前的这个实体(好友关系中,就是和当前实体本身建立关联),这里我们选择 Clazz 实体,另外我们还可以在右侧的 Data Model Inspector 面板中配置一些当前 relationship 的其他信息,2 中的 Inverse 指的是在 Clazz 实体中和 studentClass 字段反向关联的字段,根据上面的描述,这里应该指定 classStudents;3 中的 Type 可以选择关联关系的类型,有 To One 和 To Many 两种选择,分别代表对一关系和对多关系,显然一个学生只能在一个班级里,所以这里选择 To One。同样的,来创建 studentCourses 字段,创建好之后是这样的:


studentCourses-w600

接下来,再来创建另外两个实体中剩下的两个字段:

Clazz 实体里的 classStudents 字段:


classStudents-w600

Course 实体里的 courseStudents 字段:

courseStudents-w600

需要说明的是,这两个字段反向关联到 Student 实体对应的字段的类型都是一对多的,这里记得要正确设置。然后设置 Inverse 后,Student 实体里对应的 Inverse 属性也会自动设置:

Students-w600

DataModel 除了上面这种展示方式,还可以展示为关系图的形式,点击右下角的切换键就可以切换过去:


-w600

在这种模式下,各个实体之间的关系就一目了然了,单个箭头表示的是对一的关系,双箭头就表示对多的关系。从这里可以很方便地检查我们的表关系有没有设置正确。

删除规则

关联表创建好后,还差一个比较重要的属性没有介绍,就是 Relationship 的删除规则:


-w300

删除规则(Delete Rule)规定了这条数据删除时,它所关联的数据该执行什么样的操作。这里有四种规则可以选择:

  • No Action
  • Nullify
  • Cascade
  • Deny

下面通过一个例子来说明这四个类型都有什么效果:

假如我们删除一名学生,
如果把 Delete Rule 设置成 No Action,它表示不做任何,这个时候学生所在的班级(Class.classStudents)依然会以为这名学生还在这个班级里,同时课程记录里也会以为学习这门课程(Course.courseStudents)的所有学生们里,还有这位学生,当我们访问到这两个属性时,就会出现异常情况,所以不建议设置这个规则;
如果设置成 Nullify,对应的,班级信息里就会把这名学生除名,课程记录里也会把这名学生的记录删除掉;
如果设置成 Cascade,它表示级联操作,这个时候,会把这个学生关联的班级以及课程,一股脑的都删除掉,
如果 Clazz 和 Course 里还关联着其他的表,而且也设置成 Cascade 的话,就还会删除下去;如果设置成 Deny,只有在学生关联的班级和课程都为 nil的情况下,这个学生才能被删除,否则,程序就会抛出异常。
所以这里,我们把 Student 的 studentClass 和 studentCourses 的删除规则设置成 Nullify 是最合适的。


nullify-w600

实体类生成

在有关联关系的实体里,对一关系是通过对应实体类的属性来表示的,对多属性则是实体类的集合,我们可以看一下 Xcode 自动生成的实体类代码(自动生成的代码默认在 /Users/userName/Library/Developer/Xcode/DerivedData/ProjectName/Build/Intermediates/ProjectName.build/Debug-iphonesimulator/ProjectName.build/DerivedSources/CoreDataGenerated/ProjectName/):

-w600

另外对关联表进行增删改查时和单表的增删改查没太大区别,只需需要配置一下关联的属性即可。

Student *student = [NSEntityDescription   insertNewObjectForEntityForName:@"Student" inManagedObjectContext:self.context];
  
Clazz *clazz = [[Clazz alloc] initWithContext:self.context];
// configure clazz
// ....
    
student.studentClass = clazz;
    
Course *english = [[Course alloc] initWithContext:self.context];
Course *math = [[Course alloc] initWithContext:self.context];
    
[student addStudentCoursesObject:english];
[student addStudentCourses:[NSSet setWithObjects:english, math, nil]];
    
[self.context save:nil];

调用 save 后,student 和它关联的 clazz、math、english 都会保存到数据库中。

到这里,CoreData 里关联表的创建也就讲完了,下次准备在讲一下 CoreData 里的并发操作。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容