Core Data
不是数据库,⽽而是使⽤用数据库、XML、二进制⽂文件等⽅方式来存储数据的⼀个框架。git
Core Data
是iOS3以后才出现的一个框架,容许咱们以面向对象的⽅式储存和管理数据。使⽤Core Data框架,咱们能够很轻松有效地经过面向对象的接⼝管理数据。github
Core Data
框架提供了对象-关系映射(ORM)的功能,即可以将OC对象转化成数据,sql
保存在SQLite3数据库文件中,也可以将保存在数据库中的数据还原成OC对象。 在数据操做过程当中,⽆需编写任何SQL语句。数据库
##一、CoreData核心对象:多线程
NSManagedObject:
模型对象,或者叫实体(entity),可理解为OC⾥里的对象。NSManagedObjectModel:
模型文件(.xcdatamodeld),记录全部的模型对象及对象 的属性NSPersistentStoreCoordinator:
持久化存储协调者,是数据库和程序之间的桥梁, ⽤来设置数据存储的名字,位置,存储⽅式,和存储时机。用来执⾏行具体的CRUD操做。NSManagedObjectContext:
对象管理上下文,⽤户全部的持久化操做都是经过此对象。再由此对象去调用NSPersistentStoreCoordinator对象执⾏具体的操做。##二、基于SQLite数据库时,Core Data的简单使用app
和SQLite的区别:只能取出整个实体记录,而后分解,以后才能获得实体的某个属性框架
构建流程fetch
1.如果新建的工程,选择空白应用程序,next线程
2.勾选Use Core Data选项代理
此时生成的工程文件AppDelegate中,会自动生成被管理的数据上下文等相关代码
被管理的数据上下文 初始化的后,必须设置持久化存储助理
- (NSManagedObjectContext *)managedObjectContext { if (_managedObjectContext != nil) { return _managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (!coordinator) { return nil; } _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; [_managedObjectContext setPersistentStoreCoordinator:coordinator]; return _managedObjectContext; }
被管理的数据模型 初始化必须依赖.momd文件路径,而.momd文件由.xcdatamodeld文件编译而来
- (NSManagedObjectModel *)managedObjectModel { if (_managedObjectModel != nil) { return _managedObjectModel; } NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreData" withExtension:@"momd"]; _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return _managedObjectModel; }
持久化存储助理 初始化必须依赖NSManagedObjectModel,以后要指定持久化存储的数据类型,默认的是NSSQLiteStoreType,即SQLite数据库;并指定存储路径为Documents目录下,以及数据库名称
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (_persistentStoreCoordinator != nil) { return _persistentStoreCoordinator; } _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreData.sqlite"]; NSError *error = nil; NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption:@YES,NSInferMappingModelAutomaticallyOption:@YES}; NSString *failureReason = @"There was an error creating or loading the application's saved data."; if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) { NSMutableDictionary *dict = [NSMutableDictionary dictionary]; dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data"; dict[NSLocalizedFailureReasonErrorKey] = failureReason; dict[NSUnderlyingErrorKey] = error; error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict]; NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return _persistentStoreCoordinator; }
方法saveContext表示:保存数据到持久层(数据库)
- (void)saveContext { NSManagedObjectContext *managedObjectContext = self.managedObjectContext; if (managedObjectContext != nil) { NSError *error = nil; if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } } }
方法applicationDocumentsDirectory表示:应用程序沙箱下的Documents目录路径
- (NSURL *)applicationDocumentsDirectory { return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; }
3.若是不是新工程,也能够本身写入相关代码(建立一个新的工程复制过来也行)
###2.1添加数据
得到AppDelegate的代理对象
AppDelegate *delegate = [UIApplication sharedApplication].delegate;
添加实体对象
// 建立实体对象 // NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:delegate.managedObjectContext]; //添加一个实体对象到 managedObjectContext 中 User *user = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:delegate.managedObjectContext]; user.userID = @10002; user.userName = @"怀化"; user.userAge = @30; user.userSex = @"男"; user.userDate = [NSDate date];
保存上下文:
[delegate saveContext];
###2.2查询数据
建立一个取值请求:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"User"];
使用谓词设置查询条件:
request.predicate = [NSPredicate predicateWithFormat:@"userAge < 35"]; request.predicate = [NSPredicate predicateWithFormat:@"userName LIKE '*杨*'"];
设置查询的条数:
request.fetchLimit = 2;
指定从某个位置开始查询(分页效果)
request.fetchOffset = 2;
按某个字段升序、降序排列(YES为升序,NO为降序)
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"userAge" ascending:YES]; request.sortDescriptors = @[sort];
在上下文中执行取值请求:
NSArray *objects = [delegate.managedObjectContext executeFetchRequest:request error:&error]; [objects enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { User *user = (User *)obj; NSLog(@"%@ %@ %@ %@ %@",user.userID, user.userName, user.userAge, user.userSex, user.userDate); }];
###2.3 修改数据数据
查询:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"User"]; request.predicate = [NSPredicate predicateWithFormat:@"userID == '10005'"]; NSArray *objects = [delegate.managedObjectContext executeFetchRequest:request error:nil];
修改:
[objects enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { User *user = (User *)obj; user.userDate = [NSDate date]; //保存 [delegate saveContext]; }
###2.3删除数据
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"User"]; request.predicate = [NSPredicate predicateWithFormat:@"userID == '10005'"]; NSArray *objects = [delegate.managedObjectContext executeFetchRequest:request error:nil]; [objects enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { // 二、删除 [delegate.managedObjectContext deleteObject:obj]; // 三、保存 [delegate saveContext]; }];
##三、数据库依赖关系
在存在数据的过程当中,可能会遇到一些相互之间有关联的数据,好比一个学生有不少本书,每本书的属性不一样
在模型文件中,设置Relationships关系就能够添加关联关系
设置关联关系的Type为To Many就是一对多的关系,To One则为一对一
设置关联关系的 delete rule 为 cascade 时,当删除当前数据时所关联的数据也会被删除。若是为 Nullify(默认) 就不会删除关联的数据
有时在操做数据比较大的状况下,在当前线程执行会形成软件卡顿的状况,这时能够运用下列方法。
多线程下执行:
[[CoreDataManager shareManager].moContext performBlock:^{ [stus enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { Student *stu = (Student *)obj; NSLog(@"%@ %@ %@ %@ %@",stu.stuID,stu.stuName,stu.stuAge,stu.book.bookName, stu.apples); [stu.apples enumerateObjectsUsingBlock:^(Apples * _Nonnull obj, BOOL * _Nonnull stop) { Apples *apple = (Apples *)obj; NSLog(@"%@ %@",apple.appleName, apple.applePrice); }]; }]; }]; }
##四、第三方框架(MagicalRecord)使用更简单方便快捷
下载地址:https://github.com/fuxinto/MagicalRecord
Demo下载地址: