Core Data数据持久化是对SQLite的一个升级,它是ios集成的,在说Core Data之前,我们先说说在CoreData中使用的几个类。
(1)managed object model(被管理的对象模型)
是描述应用程序的数据模型,这个模型包含实体(Entity),特性(Property),读取请求(Fetch Request)等。
(2) managed object context(被管理的对象上下文)
操作实际内容, 参与对数据对象进行各种操作的全过程,并监测数据对象的变化,以提供对 undo/redo 的支持及更新绑定到数据的 UI。
作用:插入数据 查询 更新 删除
(3)persistent store coordinator(持久化存储助理)
相当于数据文件管理器,处理底层的对数据文件的读取与写入。一般我们无需与它打交道。
(4)NSFetchRequest(获取数据的请求)
相当于查询语句
(5)NSPredicate(相当于查询条件)
(6)NSEntityDescription(实体结构)
(7)后缀名为.xcdatamodel的包
里面的.xcdatamodel文件,用数据模型编辑器编辑
编译后为.momd,这就是为什么文件中没有.xcdatamodel的原因,而我们的程序中用到这个东西而不会报错的原因
数据存储(data store)
Core Data支持4中类型的数据存储:SQLiteStore, XMLStore, BinaryStore, InMemoryStore。
一、CoreData使用过程
1、创建CoreData文件(.xcdatamodel)model.xcdatamodeld编译之后会变成model.momd
创建CoreData文件,可以在创建项目的时候勾选“create CoreData”,或者自己手动添加
![](https://app.yinxiang.com/shard/s61/res/66f211aa-b57b-4318-ab69-0ae53c188791/CoreData%E6%B7%BB%E5%8A%A0Entity.png)
2、将Entity转成类
![](https://app.yinxiang.com/shard/s61/res/5b6410c1-5393-4ba0-b42c-c108eb50dd35/%E5%AF%BC%E5%87%BAEntity%E7%9A%84%E6%96%B9%E6%B3%95.png)
导出效果:
![](https://app.yinxiang.com/shard/s61/res/2d4fe1d2-7e56-4bfe-a9e5-511ac819812c/%E5%AF%BC%E5%87%BA%E7%9A%84Entity.png)
//-----------------------------------------model介绍---------------------------------------------
Model class
模型有点像数据库的表结构,里面包含Entry,实体又包含三种Property(特性):
Attribute(属性)
RelationShip(关系)
Fetched Property(读取属性)。
Attribute(属性)
RelationShip(关系)
Fetched Property(读取属性)。
Model class的名字多以 "Description" 结尾。我们可以看出:模型就是描述数据类型以及其关系的。
Managed Object Model
|
NSManagedObjectModel
|
数据模型
|
Entity | NSEntityDescription | 抽象数据类型,相当于数据库中的表 |
Property | NSPropertyDescription | Entity 特性,相当于数据库表中的一列 |
> Attribute | NSAttributeDescription | 基本数值型属性(如Int16, BOOL, Date等类型的属性) |
> Relationship | NSRelationshipDescription | 属性之间的关系 |
> Fetched Property | NSFetchedPropertyDescription | 查询属性(相当于数据库中的查询语句) |
1)Entity - NSEntityDescription
Entity 相当于数据库中的一个表,它描述一种抽象数据类型,其对应的类为 NSManagedObject 或其子类。
NSEntityDescription 常用方法:
+insertNewObjectForEntityForName:inManagedObjectContext: 工厂方法,根据给定的Entity描述,生成相应的NSManagedObject对象,并插入 ManagedObjectContext 中。
-managedObjectClassName:返回映射到Entity的NSManagedObject类名
-attributesByName:以名字为key,返回Entity中对应的Attributes
-relationshipsByName:以名字为key,返回Entity中对应的Relationships
2)Property - NSPropertyDescription
Property为Entity的特性,它相当于数据库表中的一列,或者XML文件中的value-key对中的key。它可以描述实体数据(Attribute),Entity之间的关系(RelationShip),或查询属性(Fetched Property)。
> Attribute - NSAttributeDescription
Attribute 存储基本数据,如 NSString, NSNumber or NSDate 等。它可以有默认值,也可以使用正则表达式或其他条件对其值进行限定。一个属性可以是 optional 的。
> Relationship - NSRelationshipDescription
Relationship 描述 Entity,Property 之间的关系,可以是一对一,也可以是一对多的关系。
> Fetched Property - NSFetchedPropertyDescription
Fetched Property 根据查询谓词返回指定 Entity 的符合条件的数据对象。
//-----------------------------------------使用过程---------------------------------------------
![](https://app.yinxiang.com/shard/s61/res/145f042c-560e-4a12-aade-29f115b45e2c/CoreData%E7%BB%93%E6%9E%84%E5%9B%BE%202.png)
手写配置CoreData的对象:
@property (strong, nonatomic)NSManagedObjectContext *context;
- (void)viewDidLoad {
[super viewDidLoad];
//准备工作:创建core data所需要的所有类对象,以及他们之间的关系
![](https://app.yinxiang.com/shard/s61/res/091d63f8-1c26-4f2f-866b-bd99c99c837c/Prio1.png)
//momd:model.xcdatamodeld编译之后会变成model.momd
//1.1 创建模型对象的url
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
//1.2 创建被管理对象模型
NSManagedObjectModel *objectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSManagedObjectModel *objectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
![](https://app.yinxiang.com/shard/s61/res/e4956b84-2368-4939-9baa-e3b4fa5383cc/Prio3.png)
NSPersistentStoreCoordinator *storeCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:objectModel];
//3.1 由持久化存储协调器对象创建创建出持久化存储对象(真正用来存储数据的路径)
//获取沙盒Documents路径
NSString *docmentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
//拼接真正的sqlite文件路径
NSString *sqlitePath = [docmentPath stringByAppendingPathComponent:@"Model.sqlite"];
NSURL *sqliteURL = [NSURL fileURLWithPath:sqlitePath];
NSString *docmentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
//拼接真正的sqlite文件路径
NSString *sqlitePath = [docmentPath stringByAppendingPathComponent:@"Model.sqlite"];
NSURL *sqliteURL = [NSURL fileURLWithPath:sqlitePath];
NSLog(@"sqlite路径是:%@", sqlitePath);
NSError *error = nil;
//注:可以使用匿名方法(而且是推荐使用)
NSPersistentStore *store = [storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:sqliteURL options:nil error:&error];
if (!store) {
NSLog(@"error: %@",[error userInfo]);
}
![](https://app.yinxiang.com/shard/s61/res/69786700-67d0-4295-bcd7-92b2e48ba4fa/Prio2.png)
self.context = [[NSManagedObjectContext alloc] init];
//将创建好的持久化存储协调器和被管理上下文进行绑定
[self.context setPersistentStoreCoordinator:storeCoordinator];
}
//------------------------------------------------------系统自动配置-----------------------------------------------
在创建项目的时候,勾选Use CoreData,系统会自动配置CoreData的对象。
![](https://app.yinxiang.com/shard/s61/res/0a0c3039-0632-4246-9081-cb57e20c69b0/CoreData%E8%87%AA%E5%8A%A8%E9%85%8D%E7%BD%AE.png)
因为我们可以使用的就是上下文,因此获取上下文对象就可以了
//被管理对象上下文属性
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
//使用懒加载的方式获取被管理对象上下文
- (NSManagedObjectContext *)managedObjectContext {
//如果对象为空
//获取当前程序的app单例对象:[UIApplication sharedApplication]
//获取当前程序的delegate单例对象:[[UIApplication sharedApplication] delegate]
if (!_managedObjectContext) {
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
//将delegate单例对象的上下文属性,赋值给当前类的上下文对象
_managedObjectContext = delegate.managedObjectContext;
- (NSManagedObjectContext *)managedObjectContext {
//如果对象为空
//获取当前程序的app单例对象:[UIApplication sharedApplication]
//获取当前程序的delegate单例对象:[[UIApplication sharedApplication] delegate]
if (!_managedObjectContext) {
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
//将delegate单例对象的上下文属性,赋值给当前类的上下文对象
_managedObjectContext = delegate.managedObjectContext;
}
return _managedObjectContext;
}
//------------------------------------------------------End------------------------------------------------------
//插入一条数据
- (IBAction)insertItem {
//sql语句insert into person (name, age, height) values ('bob', 19, 1.85);
//1.返回一个给定Entity和被管理对象上下文的“空的”实体对象
PersonModel * person = [NSEntityDescription insertNewObjectForEntityForName:@"PersonModel" inManagedObjectContext:self.context];
//2.将上面返回的空的实体对象进行赋值
person.name = @"Bob";
person.age = @21;
person.height = @1.85;
//3. 使用被管理对象上下文来执行插入动作(save:真正的将数据写入数据库文件中:Model.sqlite)
NSError *error = nil;
[self.context save:&error];
if (error) {
NSLog(@"插入数据失败,失败原因是:%@", error);
}
- (IBAction)insertItem {
//sql语句insert into person (name, age, height) values ('bob', 19, 1.85);
//1.返回一个给定Entity和被管理对象上下文的“空的”实体对象
PersonModel * person = [NSEntityDescription insertNewObjectForEntityForName:@"PersonModel" inManagedObjectContext:self.context];
//2.将上面返回的空的实体对象进行赋值
person.name = @"Bob";
person.age = @21;
person.height = @1.85;
//3. 使用被管理对象上下文来执行插入动作(save:真正的将数据写入数据库文件中:Model.sqlite)
NSError *error = nil;
[self.context save:&error];
if (error) {
NSLog(@"插入数据失败,失败原因是:%@", error);
}
}