一.CoreData是苹果封装的一个面向对象的数据持久化框架,使用者可以不写一条SQL语句,即可进行存储。
不是当今主流的关系型数据库,也不是对象型数据库(直接把内存中的对象塞入到数据库,对比关系型数据库而言性能不是很好,效率高)它,提供了对象-关系映射(ORM)功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象。
对象一. NSManagedObjectContext,这个对象是负责应用和数据库之前的交互,进行CURD的操作,可称之为上下文。
3上下文就相当于是一笔记本,当从数据持久层会哦去数据时,相当于将这些数据临时存放到了这个笔记本上,
然后你可以在上面CURD这些数据,除非你保存这些数据变化,否则持久层的东西是不会变化的。
接下来解释一下上下文的一下常用方法:
-save:将数据对象保存到数据文件
-objectWithID:查询指定 Managed Object ID 的数据对象
-deleteObject:将一个数据对象标记为删除,但是要等到 Context 提交更改时才真正删除数据对象
-undo回滚最后一步操作,这是都 undo/redo 的支持
-lock加锁,常用于多线程以及创建事务。同类接口还有:-unlock and -tryLock
-rollback还原数据文件内容
-reset清除缓存的 Managed Objects。只应当在添加或删除 Persistent Stores 时使用
-undoManager返回当前 Context 所使用的 NSUndoManager
-assignObject: toPersistantStore:由于 Context 可以管理从不同数据文件而来的数据对象,这个接口的作用就是指定数据对象的存储数据文件(通过指定 PersistantStore 实现)
-executeFetchRequest: error:执行获取数据请求,返回所有匹配的数据对象
对象二.NSPersistentStoreCoordinator这个对象是负责添加持久化库,通常从磁盘上的数据文件中读取或存储数据,
这些底层的读写就由它来处理,一般我们无需与它直接打交道,上下文已经封装了对它的调用。一些常用方法:
-addPersistentStoreWithType:configuration:URL:options:error:使用不同Type
加载持久化存储数据
-removePersistentStore:error:删除对应Type的持久化
-addPersistentStoreForURL:configuration:URL:options:error:加载持久化存储数据,对应的卸载接口为 -removePersistentStore:error:
-migratePersistentStore:toURL:options:withType:error:迁移数据存储,效果与 "save as"相似,但是操作成功后,迁移前的数据存储不可再使用
-managedObjectIDForURIRepresentation:返回给定 URL所指示的数据存储的 object id,如果找不到匹配的数据存储则返回 nil
-persistentStoreForURL:返回指定路径的 Persistent Store
-URLForPersistentStore:返回指定 Persistent Store 的存储路径
对象三.NSManagedObjectModel对象是加载模型文件,读取APP中的所有实体信息。可以描述程序的实体,其属性,关系的
模型图。包括以下几个部分:
1)实体(Entity)
对象四.对应NSEntityDescription对象,用来描述实体,相当于数据库中的一个表,实体名称(name)实体类名:NSManagedObject子类的名称实体实例:NSManagedObject对象或其子类的实例
NSEntityDescription 常用方法:
+insertNewObjectForEntityForName:inManagedObjectContext: 工厂方法(Demo中就是用了它来插入数据)
根据给定的 Entity 描述,生成相应的 NSManagedObject 对象,并插入 ManagedObjectContext 中。
-managedObjectClassName返回映射到 Entity 的 NSManagedObject 类名
-attributesByName以名字为 key, 返回 Entity 中对应的 Attributes
-relationshipsByName以名字为 key, 返回 Entity 中对应的 Relationships
(2)属性(Property)
对应NSPropertyDescription对象
Property 为 Entity 的特性,它相当于数据库表中的一列,或者 XML 文件中的 value-key 对中的 key。
它可以描述实体基本属性(Attribute),实体之间的关系(RelationShip),或查询属性(Fetched Property)。
<1> 实体的基本属性(Attributes)
对应NSAttributeDescription对象,存储基本数据,数据类型包括:string,date,integer(NSString, NSDate, NSNumber)
<2> 实体间的关系(Relationships)
对应NSRelationshipDescription对象,支持对一、对多的关系
<3> 查询属性(Fetched Property)
对应NSFetchedPropertyDescription对象,根据查询谓词返回指定实体的符合条件的数据对象,表示了一种“弱”的、单项的关系(相当于数据库中的查询语句)
6.持久化存储层(Persistent Stores)持久化存储层是和文件或外部数据库关联的,大多数访问持久化存储层的动作都由上下文来完成。
7.NSFetchedResultsController用于在表视图table view中加载部分数据
对象五.NSManagedObject是被管理的数据记录,相当于数据库中的一条记录。每一个NSManagedObject对象,
都有一个全局 ID(类型为:NSManagedObjectID)。每个在NSManagedObjectContext注册过的NSManagedObject,
可以通过这个全局 ID 在上下文中查询到。每个在持久存储层中的对象,都对应一个与上下文相关的NSManagedObject
常用的方法:
-entity 获取实体
-objectID 获取NSManagedObjectID
-valueForKey: 获取指定 Property 的值
-setValue: forKey: 设定指定 Property 的值
对象六.NSFetchRequest获取数据的请求,通过被管理数据的上下文来执行查询,栗子:
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
查询时,必须指定查询实体或实体名称,以 NSArray 形式返回查询结果,如果我们没有设置任何查询条件,
则返回该 Entity 的所有数据对象。
我们可以使用谓词来设置查询条件,通常会将常用的 Fetch Requests 保存到 dictionary 以重复利用。
NSFetchRequest包括以下部分:
(1)实体(Entity)的名称
(2)NSPredicate谓词(搜索关键字或限定条件)
(3)排序方式(NSArray *)sortDescriptors
所有的被管理对象(managed object)都必须在上下文中注册,而通过NSFetchRequest获得的对象自动被注册。
如果在上下文中已经存在了要获取的对象,那么这个被管理NSManagedObject将被返回。
否则上下文就会从相关的数据源中查找(也可能找不到)
例如,以下代码是查询在指定日期之后创建的ContactInfo,并将查询结果按照name排序
复制代码
NSManagedObjectContext * context = [self managedObjectContext];
NSManagedObjectModel * model = [self managedObjectModel];
NSDictionary * entities = [model entitiesByName];
NSEntityDescription * entity = [entities valueForKey:@"ContactInfo"];
NSPredicate * predicate = [NSPredicate predicateWithFormat:@"creationDate > %@", date];
NSSortDescriptor * sort = [[NSortDescriptor alloc] initWithKey:@"name"];
NSArray * sortDescriptors = [NSArray arrayWithObject: sort];
NSFetchRequest * fetch = [[NSFetchRequest alloc] init];
[fetch setEntity: entity];
[fetch setPredicate: predicate];
[fetch setSortDescriptors: sortDescriptors];
NSArray * results = [context executeFetchRequest:fetch error:nil];
[sort release];
[fetch release];
常用方法:
-setEntity:设置你要查询的数据对象的类型(Entity)
-setPredicate:设置查询条件
-setFetchLimit:设置最大查询对象数目
-setSortDescriptors:设置查询结果的排序方法
-setAffectedStores:设置可以在哪些数据存储中查询
上面的一些常用对象了解之后可以进入实战了。
首先在工程中导入CoreData库
然后新建CoreData文件
输入文件名NewsModel生成CoreData文件:
建好文件之后,在CoreData中添加你需要的表以及对应的字段属性。点击CoreData文件:
按照自己的需求添加即可。当然这里也可以重新命名
到这里CoreData的基本文件已经创建完毕。
这里有一个Demo,对CoreData的一个简单封装的工具类,简单的插入,查询,删除,更新都可以实现,
对于小项目还是合适的。大家可以在这里下载.
接下来要和大家讨论下,对于CoreData的版本升级和数据迁移的话题。
什么叫版本升级?在APP版本升级的时候,修改表字段,增加表,数据库有可能发生变化。
对于版本升级,可以有两种办法:
第一种办法:直接删掉之前的数据库,再新建新的数据库,一般不推荐此种用法,它不会保留任何历史数据,简单粗暴。
第二种办法:是进行数据迁移。而迁移又分为轻量级迁移和非轻量级迁移。轻量级迁移可以手动做一些简单的配置,采用系统自带的自动版本迁移,比较简单。
那么哪些操作是属于轻量级的呢?官方文档中介绍如下的改变支持轻量级迁移:
1.为Entity简单的添加一个属性
2.为Entity移除一个属性
3.属性值由 Optional <-> Non-optional 之间转换
4.为属性设置 Default Value
5.重命名Entity或者Attribute
6.增加一个新的relationship 或者删除一个已经存在的 relationship
7.重命名relationship
8.改变relationship to-one <-> to-many 等
9.增加,删除Entities
10.增加新的 Parent 或者 Child Entity
11.从Hierarchy中移除Entities
关于版本升级和数据迁移的更加详细的内容,在这里不做阐述。
可参考以下两篇文章:
Core Data Model Versioning and Data Migration Programming Guide