Core Data Stack学习笔记
Entity Entities 实体->数据表
一个实体可以表示一个数据模型
1> 通过图形化界面可以建立一个模型关系图,可以指定一对多,多对一,多对多的数据关系
-在数据库开发中,少用多对多关系
2> 通过工具能够自动生成对应的模型文件
3> 数据保存
NSManagedObject 被管理的对象
-开发中设计的实体,本身都是被管理对象的子类
使用CoreData的一个注意事项:如果开发时,修改过数据模型,最好将沙盒中的数据库文件删除!
使用CoreData开发的步骤
1. 首先创建一个Model,利用图形化界面创建各个实体模型
-创建完成之后,通过工具可以自动生成模型文件
-如果修改模型后,可以再次生成模型文件,会覆盖掉之前生成的文件
-自动生成的模型文件,一般不要进去改!
2. 代码
-实例化模型
-使用模型实例化持久化存储调度器
-指定存储调度器保存数据的类型以及路径
-实例化被管理对象的上下文,指定调度器
以上四步代码,在Xcode6已经封装好,可以直接使用,一般不需要程序员编写!
已经使用单例封装,可以直接调用,代码如下:
单例的.h文件
1 #import <Foundation/Foundation.h> 2 #import <CoreData/CoreData.h> 3 4 @interface CZCoreDataTools : NSObject 5 6 + (instancetype)sharedCoreDataTools; 7 8 /** 9 * 使用模型名称&数据库名称初始化Core Data Stack 10 */ 11 - (void)setupCoreDataWithModelName:(NSString *)modelName dbName:(NSString *)dbName; 12 13 /** 14 * 被管理对象的上下文 15 */ 16 @property (nonatomic, strong) NSManagedObjectContext *managedObjectContext; 17 18 /** 19 * 保存上下文 20 */ 21 - (void)saveContext; 22 23 @end
单例的.m文件
1 #import "CZCoreDataTools.h" 2 3 @implementation CZCoreDataTools 4 5 + (instancetype)sharedCoreDataTools { 6 static CZCoreDataTools *instance; 7 8 static dispatch_once_t onceToken; 9 dispatch_once(&onceToken, ^{ 10 instance = [[self alloc] init]; 11 }); 12 return instance; 13 } 14 15 // 问题:单例我们希望被广泛使用,不能确定模型的名称,同时数据库的文件名也不确定 16 - (void)setupCoreDataWithModelName:(NSString *)modelName dbName:(NSString *)dbName { 17 18 // 1. 实例化数据模型 19 NSURL *modelURL = [[NSBundle mainBundle] URLForResource:modelName withExtension:@"momd"]; 20 NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 21 22 // 2. 实例化持久化存储调度器 23 NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; 24 25 // 3. 指定保存的数据库文件,以及类型 26 // 数据库保存的URL 27 NSString *dbPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 28 dbPath = [dbPath stringByAppendingPathComponent:dbName]; 29 NSURL *dbURL = [NSURL fileURLWithPath:dbPath]; 30 31 [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:dbURL options:nil error:NULL]; 32 33 // 4. 被管理对象的上下文 34 _managedObjectContext = [[NSManagedObjectContext alloc] init]; 35 // 指定上下文的持久化调度 36 [_managedObjectContext setPersistentStoreCoordinator:psc]; 37 } 38 39 - (void)saveContext { 40 [self.managedObjectContext save:NULL]; 41 } 42 43 44 @end
// 程序启动时 初始化Core Data Stack
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// 初始化数据库
[[CZCoreDataTools sharedCoreDataTools] setupCoreDataWithModelName:@"Model" dbName:@"my.db"];
return YES;
}
3. NSEntityDescription实体描述对象,用来描述一个实体
使用方法,如果要新建一条记录,需要使用实体描述对象
// 表示要插入一条记录
// 插入Person实体描述的记录
// 插入之后,实体信息在context中维护
// 返回一个指定实体名称对应数据模型
[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.appDelegate.managedObjectContext];
// 设置模型属性
// 通知持久化数据调度器,保存数据
[self.managedObjectContext save:NULL];
提示:如果有多个实体关系,可以直接通过属性设置,就能够实现底层数据表的多表级联
程序员不需要关心底层数据库的任何实现细节
4. 在Core Data中查询数据
所有的查询是由 NSFetchedResultsController 来控制的
-首先指定”要查询的实体”以及排序的属性名称
-指定查询控制器的代理
-实现监听方法
-当要查询的实体记录发生变化,就会自动执行代理方法
在代理方法中,直接实现刷新数据工作即可
-需要查询的时候执行 performFetch:,就可以使用已经设置好的查询请求,查询数据
NSFetchedResultsController的fetchedObjects属性中保存了所有查询出来的”要查询实体”的数组
参考代码:
1 // 1. 查询请求 2 NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Person"]; 3 // 2. 排序 4 NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"personName" ascending:YES]; 5 request.sortDescriptors = @[sort]; 6 7 // 3. 设置搜索条件 - 谓词 (am, is, are) 用来定义一个物体的 8 // 在OC的开发中,通常使用谓词来过滤数据集 9 NSPredicate *p = [NSPredicate predicateWithFormat:@"personName CONTAINS %@ || company.compayName CONTAINS %@", text, text]; 10 request.predicate = p; 11 12 _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[CZCoreDataTools sharedCoreDataTools].managedObjectContext sectionNameKeyPath:nil cacheName:nil]; 13 14 // 设置代理 15 _fetchedResultsController.delegate = self;