一.数据持久化CoreData数据库框架的优势 — 是对象(更适合面向对象编程)
收菜在IOS3.0版本的系统中出现,它允许按照实体- 属性- 值 模型组织数据,并以XML,二进制文件或者SOLite数据文件的格式持久化数据
二.数据持久化CoreData常见的类
实体管理类:NsManagedObiect
实体描述类:NSEntityDescription
数据管理器类:NSManagedObjectContext — 临时的数据库(所有的操作全部在这里操作)
数据连接器类:NSPersistentStoreCoordinator —
数据模型器类:NSManagedObjectModel
存储文件 : 用来存储和管理数据的文件,IOS支持3种存储类型:NSSQLiteSToreType , NSBinaryStoreType, NSInMemoryStoreType.HTML
内存数据库—速度快.
持久化存储 :(NSPersistentStore)是对实际文件的一种Obiective - C表示方式, 一个被底层封装好的类,用于存储数据.
CoreData提供了一种简便的对象持久化管理方法,使你可以不用关心数据的存储,只需要关心对象的增加、删除、更改、读写。
基本概念
托管对象(managed object)
一个托管对象代表你想要保存到数据存储中的一个对象。这在概念上类似于SQL中的一条记录, 并且通常也包含一些域,这些域对应于你想要保存的对象的属性。
数据存储(data store)
Core Data支持4中类型的数据存储:SQLiteStore, XMLStore, BinaryStore, InMemoryStore。
托管对象上下文(managed object context)
托管对象上下文类似于应用程序和数据存储之间的一块缓冲区。这块缓冲区包含所有未被写入数据存储的托管对象。你可以添加、删除、更改缓冲区内的托管对象。在很多时候,当你需要读、插入、删除对象时,你将会调用托管对象上下文的方法。
持久化存储协调器(persistent store coordinator)
持久化存储协调器处理到数据存储的连接,并且包含一些底层信息,像用到数据存储的名字和位置。这个类通常被托管对象上下文用到。
托管对象模型(managed object model)
托管对象模型是一个类,这个类包含每一个你想存储到数据存储中的托管对象的定义。
大概是这样一种层次关系:
使用CoreData
1 在你可以读或写模型对象到当前数据存储之前,你需要实例化托管对象模型、托管对象上下文、持久化存储协调器。
托管对象模型由NSManagedObjectModel类的一个实例表示。在一个工程中我们只需要为所有的.xcdatamodeld文件实例化一个对象。
NSManagedObjectModel* managedObjectModel = [NSManagedObjectModel
mergedModelFromBundles:nil];
mergedModelFromBundles: 搜索工程中所有的.xcdatamodeld文件,并加载所有的实体到一个NSManagedObjectModel 实例中。
这样托管对象模型知道所有当前工程中用到的托管对象的定义
2 有了托管对象模型实例之后,我们就可以创建一个持久化协调器实例了。持久化协调器处理到数据存储的连接。大概是处理怎么把对象写到数据存储或怎么从数据存储读对象吧。
3 有了持久化协调器实例之后,我们需要提供一个数据存储给它管理。你可以通过发送addPersistentStoreWithType:configuration:URL:options:error:消息来实现。
4 最后一步就是实例化托管对象上下文。有了托管对象上下文,你就可以方便的管理对象了。
// // AppDelegate.m // 数据持久化CoreData1 // // Created by liuyafang on 14-10-17. // Copyright (c) 2014年 lanou3g.com 蓝鸥科技. All rights reserved. // #import "AppDelegate.h" #import "Person.h" #import "Car.h" #import "Carr.h" @implementation AppDelegate @synthesize managedObjectContext = _managedObjectContext; @synthesize managedObjectModel = _managedObjectModel; @synthesize persistentStoreCoordinator = _persistentStoreCoordinator; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; // 快速打开沙盒的方法----输出tmp文件名字 NSLog(@"%@", NSTemporaryDirectory()); /*--------第一种插入数据的方式---------*/ //实体描述的创建, ,名字是创建model的名字, 属性二:调用数据类型管理器来创建 NSEntityDescription *entiy = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:self.managedObjectContext]; //创建一个对象 属性一:给一个实体描述 属性二:调用数据类型管理器 Person *person = [[Person alloc] initWithEntity:entiy insertIntoManagedObjectContext:self.managedObjectContext]; person.name = @"Apple"; person.age = @(56); person.grade = @(89); //执行保存数据的方法 [self saveContext]; /*--------第二种插入数据的方式---------*/ // 参数1:需要实体名字 参数2: 数据管理器 Person *newPerson = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext]; newPerson.name = @"刘亚芳"; newPerson.age = @(25); newPerson.grade = @(100); //执行保存方法 [self saveContext]; /** *数据库的查找* **/ /// 查找需要描述实体 NSFetchRequest *fatch = [NSFetchRequest fetchRequestWithEntityName:@"Person"]; /// 用查找条件来查找我们想要的.......... // fatch.predicate = [NSPredicate predicateWithFormat:@"name = ‘刘亚芳‘ AND age > ‘22‘"]; /// 借助数据管理器来操作 NSArray *array = [self.managedObjectContext executeFetchRequest:fatch error:nil]; /// 打印的最新的操作数据,其余的是对象的指针; NSLog(@"%@",array); for (int i = 0; i < array.count; i++) { Person *per = array [i]; NSLog(@"查找name = :%@", per.name); } /* //输出第一条数据 Person *per = array [0]; NSLog(@"per - name :%@", per.name); NSLog(@"per - age:%@", per.age); NSLog(@"per - garde:%@", per.grade); */ /** *数据库修改* **/ Person *per = array[1]; per.name = @"修改后的名字"; [self saveContext]; Carr *car = [NSEntityDescription insertNewObjectForEntityForName:@"Carr" inManagedObjectContext:self.managedObjectContext]; car.name = @"奥迪"; car.number = @"454545"; [per addCarObject:car]; /** *数据库的删除* **/ //删除的是一个对象 // [self.managedObjectContext deleteObject:per]; [self saveContext]; NSLog(@"------------------%@",per.car); /** -----数据的升级(updata)的步骤------ **/ /// 1.先添加新的版本表 /// 2.添加属性 /// 3.Model Version改成升级的版本表 /// 4.ctrl+N 新建一个Mapping Model --原来的版本表///---升级的版本表 /// 5.最后进行一个配置 NSDictionary *dic = @{NSMigratePersistentStoresAutomaticallyOption: @(YES)}; --支持自动升级版本 /// 嵌套表 //新建一个实体Car //调用appdelegate // AppDelegate *appdelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; // appdelegate.managedObjectContext return YES; } - (void)applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - (void)applicationDidEnterBackground:(UIApplication *)application { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - (void)applicationDidBecomeActive:(UIApplication *)application { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - (void)applicationWillTerminate:(UIApplication *)application { // Saves changes in the application‘s managed object context before the application terminates. [self saveContext]; } - (void)saveContext { NSError *error = nil; //获取数据管理器 NSManagedObjectContext *managedObjectContext = self.managedObjectContext; // 首先判断是否有改变(数据管理器--临时数据库) if (managedObjectContext != nil) { if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { // Replace this implementation with code to handle the error appropriately. // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } } } #pragma mark - Core Data stack // Returns the managed object context for the application. // If the context doesn‘t already exist, it is created and bound to the persistent store coordinator for the application. - (NSManagedObjectContext *)managedObjectContext { ///懒加载 if (_managedObjectContext != nil) { return _managedObjectContext; } //1.创建数据管理器 ,需要数据连接器 NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { //给数据连接器指定一个数据管理器 ,实际中应用到的只有诗句管理器. _managedObjectContext = [[NSManagedObjectContext alloc] init]; [_managedObjectContext setPersistentStoreCoordinator:coordinator]; } return _managedObjectContext; } // Returns the managed object model for the application. // If the model doesn‘t already exist, it is created from the application‘s model. - (NSManagedObjectModel *)managedObjectModel { if (_managedObjectModel != nil) { return _managedObjectModel; } //3.根据数据表的url来创建一个model NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"_____CoreData1" withExtension:@"momd"]; _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return _managedObjectModel; } // Returns the persistent store coordinator for the application. // If the coordinator doesn‘t already exist, it is created and the application‘s store added to it. - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (_persistentStoreCoordinator != nil) { return _persistentStoreCoordinator; } //2.数据连接器初始化,创建一个数据库 NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"_____CoreData1.sqlite"]; NSError *error = nil; ///数据连接器的创建,需要创建一个model _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; // 数据连接器 添加一个数据库的类型(数据库,xml,内存等),然后进行一些配置 NSDictionary *dic = @{NSMigratePersistentStoresAutomaticallyOption: @(YES)}; ///进行的一些设置 ---就是支持自动升级 if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:dic error:&error]) { /* Replace this implementation with code to handle the error appropriately. abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. Typical reasons for an error here include: * The persistent store is not accessible; * The schema for the persistent store is incompatible with current managed object model. Check the error message to determine what the actual problem was. If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application‘s resources directory instead of a writeable directory. If you encounter schema incompatibility errors during development, you can reduce their frequency by: * Simply deleting the existing store: [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil] * Performing automatic lightweight migration by passing the following dictionary as the options parameter: @{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES} Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details. */ // 当数据库找不到表,输出报错信息,ablrt()中断 NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } //如果成功,返回数据连接器 return _persistentStoreCoordinator; } #pragma mark - Application‘s Documents directory // Returns the URL to the application‘s Documents directory. - (NSURL *)applicationDocumentsDirectory { //获取沙盒的路径 return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; } @end