背景
近期公司项目需要本地持久化保存一些用户信息数据,由于数据量的问题还有无需删除后保留,选择了使用数据库来保存这些信息。iOS数据库使用,大致有FMDB、WCDB、CoreData、Relam等,本次使用CoreData进行数据留存,作为随笔,后续其他数据库相关在后续学习中再行添加更新。
CoreData
CoreData是Apple 提供的一个用来管理轻量化数据库的框架,这个框架可以在单个设备上,本地化保存app的永久数据、缓存暂时数据、以及对数据的撤销操作等,使用CoreData,我们无需直接对数据库进行sql的语法操作,通过CoreData来在运行时中管理,CoreData通过抽象你的对象到存储区映射的细节,使得app能更简单的管理数据,无需直接操纵数据库。
CoreData创建
创建项目时勾上CoreData(Tip:也可以自己后续添加)
左侧文件树目录会出现一个.xcdatamodeld的文件,这个文件就是我们创建entity、建表、操作属性的地方。打开该文件。
如图,左侧列表为我们在该模型文件中的:Entites 实体
、Fetch Requests 请求模板
、Configurations 配置信息
,可以通过左下角加号按钮进行分别添加。
Entity
添加entity后,右侧列表中展示了该entity的具体结构信息,分为三部分:Attributes 属性
、Relationships 关联
、Fetched Properties 获取操作
。
-
Attributes
Attributes即为实体属性,我们需要为存储的属性创建对应的键,包括名字以及类型。这里介绍一下具体的属性类型以及一般我们常用的一些类型:- String: 字符串,在对应的类文件中以
NSSString
表示 - Boolean: 布尔值,以
NSNumber
表示 - Float: 单精度浮点小数
- Double: 双精度浮点小数
- Integer16 32 64: 整数,不同的范围,一般都用16,如果是为枚举类型而设立,可以使用16,对应类名中使用
NSNumber
,调用时记得取intValue
即可。 - Date: 时间,以
NSDate
表示 - Binary Data: 二进制数据,以
NSData
表示 - Transformable: OC对象,自动创建时以
id
表示,在对应的类文件中,我们可以改为具体的OC类名,但是该对象必须遵守NSCoding
协议。
- String: 字符串,在对应的类文件中以
-
Relationships
Relationships为实体关联关系,顾名思义可将不同实体建立联系,CoreData会在该实体下一个属性,将之与被关联的实体所对应的属性关联起来。如图所示:
Destination表明为目标关联实体,Inverse表明为对应的关系,这样将一个addressmodel添加进accountmodel的同时,该addressmodel的relationship也会自动指向accountmodel,双方形成对应。
熟悉sqlite的朋友,其实relationship类似于外键,定义了实体之间的关系,type
分为两种:一对一、一对多,对多关系的时候使用NSSet
来存储模型。 Fetched Properties
定义查询操作,但我们一般都是在具体代码环境下具体定义操作,所以一般不怎么在这里设置。
- Data Model Inspector
除开以上,我们可以对具体的entity、relationship进行一些属性上的设置:
对于attribute:
- default value: 设置默认值,注意二进制类型无法设置
- optional: 代表可选,如果为NO,在进行save操作时该属性必须有值,否则返回error,默认为YES。
- transient: 设置当前属性是否只保存在内存中,如果为YES,该属性将不会被本地持久化,适合用于存储一些内存中缓存的数据,比如一些临时的每次都会变更的数据。
- index: 索引设置
- Validation:
Validation
可以设置最大值与最小值来约束数据,数值类型为大小,字符串为长度、时间为约定时间。 - Reg.Ex: 正则,设置正则表达式来约束数据,只用于验证和控制,并不对数据产生影响。
对于relationship:
- Delete Rule: 删除规则,用于规定,当前对象被删除后,与之关联的对象的反应
NSNoActionDeleteRule 删除后无操作,关联对象的关联属性不会被指向nil,注意此时再使用关联对象的关联属性可能会出现问题。
NSNullifyDeleteRule 删除后置nil,将关联对象的关联属性指向nil,为默认设置
NSCascadeDeleteRule 级联删除,将关联对象一起删除
NSDenyDeleteRule 拒绝删除,如果当前对象还指向其他关联对象,则当前对象不能被删除
对于entity:
- Parent Entity: 设置父类实体,子类会继承父类的数据,但是这些数据会存于父类实体的表当中,当多个子类继承于同一父类时,所有子类的父类部分都会存放于父类表中,这里会有性能问题。(继承属性名字不要相同)
Fetch Requests
一些更加简单直观的请求配置,一般也不做设定。
可视化模型
CoreData右下角界面的editor style,可以使我们自由切换表格展示或者是图形可视化展示,更加轻松的看到实体与属性的关系,实体与实体之间的联系。如上图。
创建托管对象类文件
当我们在模型中创建好实体后,就要根据实体,生成我们在具体开发中使用的,基于NSManagedObject
类的托管类对象文件了,我们通过这类对象来进行对数据库的操作。
xcode为我们提供了自动化生成的方式,在菜单栏Editor -> Create NSManagedObject Subclass -> 选择对应数据库版本(后续再说数据库版本相关) -> 勾选对应要生成托管类的实体 -> 生成文件
。图略
在左侧文件数列表可见,每个实体都对应生成了4个文件:
分别是以实体名开头的.h
、.m
以及实体的Category
文件
托管对象类文件
以实体名生成的文件,这个文件xcode没有生成任何多余的代码,是用来让我们添加自己的用来管理操作数据库的的相关逻辑代码,相当于一层单例Manager,我们自己app内的增删改查方法逻辑就写在这里(app -> CoreData),方法内的具体CoreData Api调用才是操作数据库的一层(CoreData -> Database)。
如果有设置relationship,类文件会声明@class
Category 分类
点开分类,里面有xcode自动生成的一系列代码,包括我们在xcdatamodeld中设置的实体属性:
如果我们设置的relationship的type为一对多,那么就会有CoreDataProperties 实体属性
以及CoreDataGeneratedAccessors 对多属性集合方法
前者表明具体实体的Attributes
、Relationships
,后者为系统生成的管理对多方法,都是在运行时中动态实现的,分类文件可以不管。
前文有提到设置属性的类型,xcode为我们自动生成的分类文件中,transformalbe的位置是id
,需要我们手动改写成我们需要的类名(遵守NSCoding协议,因为要被归档),其他数值类型的默认都为NSNumber,当然创建托管类对象文件的时候可以勾选Use scalar properties for primitive data types
来生成具体对应的标量类型属性,那创建出来就是具体的比如int_16
、double
等类型。
注意当更新属性后,要记得重新生成托管类对象文件!!!
基本的介绍以及创建过程就是这样,后续会更新CoreData 内对于数据库的操作!谢谢。
一些小问题(更新)
- 当我们创建xcdatamodeld的同时,Core Data就已经生成了对应的default文件了,只是左侧的文件树目录看不到,这时候如果我们再手动生成托管类对象文件的时候,编译器就会报重复错误,需要在xcddatamodeld中,选择每个实体,将Inspector中的Codegen选项,选择
Manual/None
即可