CoreData基础
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”,或者自己手动添加
2、将Entity转成类
导出效果:
//-----------------------------------------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 的符合条件的数据对象。
//-----------------------------------------使用过程---------------------------------------------
手写配置CoreData的对象:
@property (strong, nonatomic)NSManagedObjectContext *context;
- (void)viewDidLoad {
[super viewDidLoad];
//准备工作:创建core data所需要的所有类对象,以及他们之间的关系
创建持久化存储协调器(助理)
//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];
真正创建持久化存储协调器对象,并和被管理对象进行绑定
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]);
}
创建被管理对象上下文
self.context = [[NSManagedObjectContext alloc] init];
//将创建好的持久化存储协调器和被管理上下文进行绑定
[self.context setPersistentStoreCoordinator:storeCoordinator];
}
//------------------------------------------------------系统自动配置-----------------------------------------------
在创建项目的时候,勾选Use CoreData,系统会自动配置CoreData的对象。
因为我们可以使用的就是上下文,因此获取上下文对象就可以了
//被管理对象上下文属性
@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);
}
}