简介
CoreData提供了对象关系映射(ORM)功能,从效果上说就是创建了一个"虚拟对象数据库",也可以把它看作一个综合的数据库管理库。
NSManagedObjectContext
被管理的数据上下文对象,主要负责应用和数据库之间的交互。我们就是用它来进行增删改查操作。它会记录用户对数据的所有改变。它有NSPersistentStoreCoordinator
属性。创建它需要设置NSPersistentStoreCoordinator。
NSPersistentStoreCoordinator
持久化数据协调库,用于添加持久化存储库,相当于数据库的连接器。也就是我们用数据库做持久化还是用XML做持久化是由它决定的。我们用它来设置存储库的类型和指定存储库的路径。它有NSManagedObjectModel属性。
NSManagedObjectModel
NSManagedObjectModel代表CoreData的模型文件。CoreData项目中有一个.xcdatamodeld文件,它就是CoreData的模型文件。我们在.xcdatamodeld文件里进行创建实体和添加实体的属性。所以所有的实体信息都在NSManagedObjectModel中。
NSManagedObject
NSManagedObject对应实体,NSManagedObject是实体的映射,被CoreData管理的数据记录。也就是说在CoreData中我们直接操作的数据对象是NSManagedObject,你可以把它们当做一个东西,但是在代码中我们使用NSManagedObject。
NSEntityDescripition
实体描述类。包含实体的名字和属性。可以通过它来操作指定的实体。
基于SQLite简单使用
1.创建工程
若是新建的工程,勾选Use Core Data选项
AppDelegate文件中自动生成被管理数据上下文等相关代码,不用我们自己来进行相关的配置,可以直接使用。
在AppDelegate.h文件中添加如下代码:
/** * 上下文对象,负责应用和数据库之间的交互。我们就是用它来操作实体,进行增删改查等操作 */ @property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; /** * 管理数据模型,代表CoreData的模型文件。包含了所有实体的信息。 */ @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel; /** * 持久性数据协调器,添加持久化存储裤。在这里设置使用数据库还是xml等存储裤来做持久化,以及存储裤的路径 */ @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; //保存数据到持久层(数据库) - (void)saveContext; //应用程序沙盒Document目录 - (NSURL *)applicationDocumentsDirectory;
在AppDelegate.m文件中:
保存数据到持久层
- (void)applicationWillTerminate:(UIApplication *)application { [self 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(); } } }
被管理的数据模型
- (NSManagedObjectModel *)managedObjectModel { if (_managedObjectModel != nil) { return _managedObjectModel; } //指定.xcdatamodeld文件,该文件编译后会变为momd文件 NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataDemo" withExtension:@"momd"]; _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return _managedObjectModel; }
持久性数据协调器
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (_persistentStoreCoordinator != nil) { return _persistentStoreCoordinator; } _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; //数据库路径 NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataDemo.sqlite"]; NSError *error = nil; NSString *failureReason = @"There was an error creating or loading the application's saved data."; /* addPersistentStoreWithType:指定存储类型 NSSQLiteStoreType: 数据库 NSXMLStoreType: XML NSBinaryStoreType: 二进制文件 NSInMemoryStoreType: 内存形式 */ if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { // Report any error we got. 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; }
被管理数据上下文
- (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; }
如果不是新工程建模后加入这些代码即可
2.添加实体
在工程中选中.xcdatamdeld文件
点击
在右侧栏对实体命名
或者双击默认实体名进行命名
点击Add Attribute添加实体属性
如果一个实体中包含另一个实体,例如有一个实体Person还有一个实体Card。Person中有一个属性card,Card中也有一个属性person。那么就需要建立两个实体间的关系。如果下图这个页面,点击上图的Editor Style按钮切换一下。
两个实体都按这种方法创建关系。
选中关系,在右侧Delete Rule可以设置删除规则
关联模式Cascade,一个数据被删除,另一个实体的数据也会删除。
按Editor Style按钮切换到另一种视图模式,最终两个实体关系图为:
3.为每个实体生成NSManagedObject子类
具体的类名就是实体的class,默认情况下就是实体的名字。如果不想用实体名字做类名只需更改实体的class:
4.插入数据
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; //获取上下文 NSManagedObjectContext *contxt = [appDelegate managedObjectContext]; //创建Person对象。创建被管理的NSManagedObject对象,指定实体名字 Person *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:contxt]; //设置person属性 [person setValue:@"小小" forKey:@"name"]; [person setValue:[NSNumber numberWithInt:29] forKey:@"age"]; //创建Card对象。 Card *card = [NSEntityDescription insertNewObjectForEntityForName:@"Card" inManagedObjectContext:contxt]; //设置card属性 [card setValue:[NSNumber numberWithInt:130] forKey:@"num"]; //设置对象间关系 [person setValue:card forKey:@"card"]; [card setValue:person forKey:@"person"]; NSError *error = nil; /* hasChanges:判断数据是否有变化 save:保存数据变化,并将其同步到持久化数据文件中 */ if ([contxt hasChanges] && ![contxt save:&error]) { NSLog(@"插入失败:%@,%@",error,error.userInfo); } else { NSLog(@"插入成功"); }
5.查询数据
AppDelegate *appDelegate = [[AppDelegate alloc] init]; NSManagedObjectContext *cxt = [appDelegate managedObjectContext]; //实体关联的描述类,指定实体名字获取 NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:cxt]; //数据提取请求类 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; //实体描述设定到请求对象中 fetchRequest.entity = entity; //查询条件,如果想查询全部补设置查询条件即可 fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name=%@",@"小明"]; //排序,指定排序字段和排序方式。根据年龄正序排序 NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"age" ascending:YES]; //把排序描述设定到请求对象中 NSArray *sortDescriptors = @[sortDescriptor]; fetchRequest.sortDescriptors = sortDescriptors; //限制一次提取数据的纪录数 fetchRequest.fetchLimit = 10; NSError *error = nil; //请求查询,返回数组中存放被管理的ModelManagedObject实体对象 NSArray *listData = [cxt executeFetchRequest:fetchRequest error:&error]; for (Person *person in dataList) { NSLog(@"\nname:%@\tage:%@\ncard:%@",person.name,person.age,person.card.num); }
6.删除数据
AppDelegate *appDelegate = [[AppDelegate alloc] init]; NSManagedObjectContext *cxt = appDelegate.managedObjectContext; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Model" inManagedObjectContext:cxt]; NSFetchRequest *request = [[NSFetchRequest alloc] init]; request.entity = entity; request.predicate = [NSPredicate predicateWithFormat:@"title=%@",model.title]; NSError *error = nil; NSArray *listData = [cxt executeFetchRequest:request error:&error]; if (listData.count > 0) { ModelManagedObject *modelObject = [listData lastObject]; [cxt deleteObject:modelObject]; error = nil; if ([cxt hasChanges] && ![cxt save:&error]) { NSLog(@"删除数据失败:%@",[error userInfo]); } else { NSLog(@"删除数据成功"); } }
7.修改数据
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; NSManagedObjectContext *contxt = [appDelegate managedObjectContext]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:contxt]; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; fetchRequest.entity = entity; fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name=%@",@"小明"]; NSArray *dataList = [contxt executeFetchRequest:fetchRequest error:nil]; Person *p = dataList.lastObject; p.name = @"小红"; if ([contxt hasChanges] && ![contxt save:nil]) { NSLog(@"修改失败"); } else { NSLog(@"修改成功"); }