上篇博客中讲了 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 里的并发操作。

CoreData 从入门到精通(三)关联表的创建的更多相关文章

  1. iOS开发-UI 从入门到精通(三)

    iOS开发-UI 从入门到精通(三)是对 iOS开发-UI 从入门到精通(一)知识点的综合练习,搭建一个简单地登陆界面,增强实战经验,为以后做开发打下坚实的基础! ※在这里我们还要强调一下,开发环境和 ...

  2. CoreData 从入门到精通(五)CoreData 和 TableView 结合

    我们知道 CoreData 里存储的是具有相同结构的一系列数据的集合,TableView 正好是用列表来展示一系列具有相同结构的数据集合的.所以,要是 CoreData 和 TableView 能结合 ...

  3. centos 安装oracle 11g r2(三)-----表空间创建

    centos 安装oracle 11g r2(三)-----表空间创建 创建表空间前要保证监听与数据库实例已经启动 1.启动监听 [oracle@localhost ~]$ lsnrctl start ...

  4. 多对多第三张表的创建方式 和 forms组件的使用

    目录 一.多对多第三张表的创建 1. 全自动方式 (1)实现代码 (2)优点和不足 2. 纯手撸方式(了解) (1)实现代码 (2)优点和不足 3. 半自动方式(推荐使用) (1)实现代码 (2)优点 ...

  5. MyBatis从入门到精通(三):MyBatis XML方式的基本用法之多表查询

    最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 1. 多表查询 上篇博客中,我们示例的 ...

  6. CoreData 从入门到精通(六)模型版本和数据迁移

    前面几篇文章中讲的所有内容,都是在同一个模型版本上进行操作的.但在真实开发中,基本上不会一直停留在一个版本上,因为需求是不断变化的,说不定什么时候就需要往模型里添加新的字段,添加新的模型,甚至是大规模 ...

  7. CoreData 从入门到精通(二) 数据的增删改查

    在上篇博客中,讲了数据模型和 CoreData 栈的创建,那下一步就是对数据的操作了.和数据库一样,CoreData 里的操作也无非是增删改查.下面我们将逐步讲解在 CoreData 中进行增删改查的 ...

  8. visual studio 2015 搭建python开发环境,python入门到精通[三]

    在上一篇博客Windows搭建python开发环境,python入门到精通[一]很多园友提到希望使用visual studio 2013/visual studio 2015 python做demo, ...

  9. CoreData 从入门到精通 (一) 数据模型 + CoreData 栈的创建

    CoreData 是 Cocoa 平台上用来管理模型层数据和数据持久化的一个框架,说简单点,就是一个数据库存储框架.CoreData 里相关的概念比较多,而且初始化也非常繁琐,所以对初学者的学习还是有 ...

随机推荐

  1. 并行编程(1) - sum.msic.Unsafe 一

    相信看过java源代码的同学.对 sum.msic.Unsafe 这个类并不陌生,特别是在java.util.concurrent包有非常多的使用. sum.msic.Unsafe源代码:      ...

  2. Docker容器查看ip地址

    第一步:进入centos7容器:yum install net-tools -y     我这里已经加载过,所以没有继续加载 第二步:加载完成之后可以输入 ifconfig查看ip地址

  3. 12. Integer to Roman[M]整数转罗马数字

    题目 Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from ...

  4. Rabbit MQ 学习 (一)Window安装Erlang环境

    之前也没有用过Rabbit MQ ,最近正在学习中,记性不好,特意记一下. 百度一下 先得 安装 Erlang 并且 设置环境变量. 在Erlang 官网去下载,那个慢呀... 还好CSDN 里有人提 ...

  5. Centos7 minimal 系列之Nginx搭建(三)

    一.安装nginx 1.1.安装依赖包 yum -y install gcc-c++ yum -y install pcre pcre-devel yum -y install zlib zlib-d ...

  6. The Vertica Analytic Database:C-Store 7 Years Later笔记

    1.设计目标 Vertica数据库可以说是7年之后的C-Store,在2012年发表的这样一篇论文,描述了现在基于C-Store的一部分改进,当然,Vertica借鉴了很多C-Store的思想,但并非 ...

  7. LeetCode Golang 单向链表相加 反向实现

    LeetCode 两数之和, 反向实现 1 -> 2 -> 3 -> 4 +                  3 -> 4 ------------------------- ...

  8. Java基础——过滤器和监听器

    什么是过滤器? Servlet过滤器和Servlet十分相似,但它具有拦截客户端请求的功能,Servlet过滤器可以改变请求中的内容,来满足实际开发中的需要.对于开发人员而言,过滤器实际上就是在Web ...

  9. maven的pom.xml配置json依赖

    <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</art ...

  10. No content type provided for validation of a content model---WebLogic问题

    一个web项目,复制到Weblogic domain下的autodeploy目录下,可是从BEA管理控制台中的Deployments下却找不到该项目,奇怪了,这个以前拷过来就可以用的啊?! 查看控制台 ...