Coredata — 入门使用
CoreData的底层实现尽管是使用的sqlite数据库。但是CoreData在使用起来但是和sqlite大相径庭。可能你会发现你连一句sql语句都不要写。CoreData存在于应用程序和持久化存储区之间,扮演了桥梁的角色,将托管的对象映射到持久化存储区其中。
1.设置上下文
在代码開始之前还须要加入CoreData框架,并在合适的地方引入头文件<CoreData/CoreData.h>:

- // 从应用程序包中载入模型文件
- NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
- // 传入模型对象。初始化NSPersistentStoreCoordinator
- NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
- // 构建SQLite数据库文件的路径
- NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"model.data"];
- // 将数据库路径转成URL
- NSURL *url = [NSURL fileURLWithPath:filePath];
- // 加入持久化存储库,这里使用SQLite作为存储库
- NSError *error = nil;
- NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error];
- // 推断数据库是否加入成功
- if (store == nil) {
- [NSException raise:@"加入数据库错误" format:@"%@", [error localizedDescription]];
- }
- // 初始化上下文
- NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
- // 设置persistentStoreCoordinator属性
- context.persistentStoreCoordinator = psc;
2.加入数据
- // 创建一个Husband实体对象,传入上下文
- NSManagedObject *husband = [NSEntityDescription insertNewObjectForEntityForName:@"Husband" inManagedObjectContext:context];
- // 通过键值编码的方式设置Husband的name属性
- [husband setValue:@"jack" forKey:@"name"];
- // 通过coredata生成的实体类来创建一个Wife实体对象,传入上下文
- Wife *wife = [NSEntityDescription insertNewObjectForEntityForName:@"Wife" inManagedObjectContext:context];
- // 通过setter方法设置属性
- wife.name = @"rose";
- // 设置Husband和Wife之间的关联关系(一方关联,还有一方自己主动关联)
- wife.husband = husband;
- // 利用上下文对象,将数据同步到持久化存储库
- BOOL success = [context save:&error];
- if (!success) {
- [NSException raise:@"訪问数据库错误" format:@"%@", [error localizedDescription]];
- }
- // 假设是想做更新操作:须要将实体对象先查询出来。在更改了实体对象的属性后调用[context save:&error],就能将更改的数据同步到数据库
3.查询数据
- // 初始化一个查询请求
- NSFetchRequest *request = [[NSFetchRequest alloc] init];
- // 设置要查询的实体
- request.entity = [NSEntityDescription entityForName:@"Husband" inManagedObjectContext:context];
- // 设置排序(依照name降序)
- NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:NO];
- request.sortDescriptors = [NSArray arrayWithObject:sort];
- // 设置条件过滤(搜索name中包括字符串"ja"的记录)
- NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@", @"*ja*"];
- request.predicate = predicate;
- // 运行请求,返回一个数组
- NSArray *objs = [context executeFetchRequest:request error:&error];
- if (error) {
- [NSException raise:@"查询错误" format:@"%@", [error localizedDescription]];
- }
- // 遍历数据
- for (NSManagedObject *obj in objs) {
- NSLog(@"name=%@", [obj valueForKey:@"name"]);
- // 实体属性中包括还有一个实体。不须要再次设置查询请求,Core Data会依据关联关系查询到关联的实体信息
- NSLog(@"wife = %@", [[obj valueForKey:@"wife"] valueForKey:@"name"]);
- }
fetchRequest相当于sql查询语句的包装类。须要用setEntity方法,来指定详细查询的实体结构(表结构);
通过NSEntityDescription的entityForName方法来。返回指向该详细实体结构的指针;
然后调用executeFetchRequest:error:方法,来运行查询操作,假设操作成功,则返回相应的数据记录数组。
当中,能够通过NSManagedObject数据记录对象里关联的属性,查询还有一个数据记录对象里的属性;
CoreData不会依据实体中的关联关系马上获取对应的关联对象,比方通过CoreData取出Husband实体时。并不会马上查询相关联的Wife实体;当应用真的须要使用Wife时,才会再次查询数据库。载入Wife实体的信息。这个就是CoreData的延迟载入机制。

4.删除数据
Core Data的增删改使用的方法都是save:方法,在上下文调用save方法之前,全部的数据改动都是发生在内存中的。仅仅有调用save方法后,上下文中发生的数据改动才会被写入到持久化存储区。
获取到须要删除的实体对象之后。调用deleteObject:方法就能够从上下文中删除这个实体对象了,最后须要调用save:方法同步改动到数据库中:
- // 初始化一个查询请求
- NSFetchRequest *request = [[NSFetchRequest alloc] init];
- // 设置要查询的实体
- request.entity = [NSEntityDescription entityForName:@"Husband" inManagedObjectContext:context];
- // 设置条件过滤(搜索name等于jack2的实体)
- NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == %@", @"jack2"];
- request.predicate = predicate;
- // 运行请求,返回一个数组
- NSArray *objs = [context executeFetchRequest:request error:&error];
- if (error) {
- [NSException raise:@"查询错误" format:@"%@", [error localizedDescription]];
- }
- // 遍历数据
- for (NSManagedObject *obj in objs) {
- // 传入须要删除的实体对象
- [context deleteObject:obj];
- // 将结果同步到数据库
- [context save:&error];
- if (error) {
- [NSException raise:@"删除错误" format:@"%@", [error localizedDescription]];
- }
- }
5.新建project时勾选Use Core Data选项的情况
在新建project时使用CoreData,系统会帮我们在AppDelegate中搭建好一个上下文环境,我们能够在其它的controller中去使用这个context,省去了自己搭建上下文的操作,使用起来很简便。
AppDelegate.h中:
- @interface AppDelegate : UIResponder
- @property (strong, nonatomic) UIWindow *window;
- // 搭建上下文环境须要使用的对象
- @property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
- @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
- @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- // 保存实体对象到数据库中
- - (void)saveContext;
- // 取得程序沙盒路径的URL
- - (NSURL *)applicationDocumentsDirectory;
- @end
AppDelegate.m中:
- #pragma mark - Core Data stack
- @synthesize managedObjectContext = _managedObjectContext;
- @synthesize managedObjectModel = _managedObjectModel;
- @synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- - (NSURL *)applicationDocumentsDirectory {
- // The directory the application uses to store the Core Data store file. This code uses a directory named "edu.hcit.qqqqq" in the application's documents directory.
- return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
- }
- - (NSManagedObjectModel *)managedObjectModel {
- // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
- if (_managedObjectModel != nil) {
- return _managedObjectModel;
- }
- /**************************************************************************************************/
- // model 是模型文件的名称,默认是和项目名称同样的
- NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"model" withExtension:@"momd"];
- _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
- return _managedObjectModel;
- }
- - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
- // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it.
- if (_persistentStoreCoordinator != nil) {
- return _persistentStoreCoordinator;
- }
- // Create the coordinator and store
- _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
- /**************************************************************************************************/
- // 以下的数据库 model.sqlite 是存储实体数据的数据库
- NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"model.sqlite"];
- NSError *error = nil;
- NSString *failureReason = @"There was an error creating or loading the application's saved data.";
- 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];
- // Replace this 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();
- }
- return _persistentStoreCoordinator;
- }
- - (NSManagedObjectContext *)managedObjectContext {
- // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
- if (_managedObjectContext != nil) {
- return _managedObjectContext;
- }
- NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
- if (!coordinator) {
- return nil;
- }
- _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
- [_managedObjectContext setPersistentStoreCoordinator:coordinator];
- return _managedObjectContext;
- }
- #pragma mark - Core Data Saving support
- - (void)saveContext {
- NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
- if (managedObjectContext != nil) {
- NSError *error = 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();
- }
- }
- }
假设在一个已有的project中加入CoreData。搭建上下文时能够新建一个使用CoreData的project,将上述的代码复制到已有project,在AppDelegate.m中将模型文件的名称和数据库名称稍作改动就可以。数据的操作方法与上文类似。
6.打印隐藏的SQL语句
在Edit Scheme中选择Run,之后进入Arguments标签,加入參数:“-com.apple.CoreData.SQLDebug 1”


打开SQL语句隐藏开关后,程序在执行时。debug日志里会打印程序执行的SQL语句:

Coredata — 入门使用的更多相关文章
- iphone dev 入门实例4:CoreData入门
The iPhone Core Data Example Application The application developed in this chapter will take the for ...
- CoreData 从入门到精通(五)CoreData 和 TableView 结合
我们知道 CoreData 里存储的是具有相同结构的一系列数据的集合,TableView 正好是用列表来展示一系列具有相同结构的数据集合的.所以,要是 CoreData 和 TableView 能结合 ...
- CoreData 从入门到精通(六)模型版本和数据迁移
前面几篇文章中讲的所有内容,都是在同一个模型版本上进行操作的.但在真实开发中,基本上不会一直停留在一个版本上,因为需求是不断变化的,说不定什么时候就需要往模型里添加新的字段,添加新的模型,甚至是大规模 ...
- CoreData 从入门到精通(四)并发操作
通常情况下,CoreData 的增删改查操作都在主线程上执行,那么对数据库的操作就会影响到 UI 操作,这在操作的数据量比较小的时候,执行的速度很快,我们也不会察觉到对 UI 的影响,但是当数据量特别 ...
- CoreData 从入门到精通(三)关联表的创建
上篇博客中讲了 CoreData 里增删改查的使用,学到这里已经可以应对简单的数据存储需求了.但是当数据模型复杂起来时,例如你的模型类中除了要存储 CoreData 里支持的数据类型外,还有一些自定义 ...
- CoreData 从入门到精通(二) 数据的增删改查
在上篇博客中,讲了数据模型和 CoreData 栈的创建,那下一步就是对数据的操作了.和数据库一样,CoreData 里的操作也无非是增删改查.下面我们将逐步讲解在 CoreData 中进行增删改查的 ...
- CoreData 从入门到精通 (一) 数据模型 + CoreData 栈的创建
CoreData 是 Cocoa 平台上用来管理模型层数据和数据持久化的一个框架,说简单点,就是一个数据库存储框架.CoreData 里相关的概念比较多,而且初始化也非常繁琐,所以对初学者的学习还是有 ...
- CoreData的使用入门到精通
源码下载地址: http://download.csdn.net/download/huntaiji/6664567 一,创建项目文件--选择Empty Application 起名:CoreDat ...
- Core Data浅谈初级入门
Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象.在此数 ...
随机推荐
- windows提权的几种姿势
想象这种画面:你拿到了一台机器上Meterpreter会话了,然后你准备运行 getsystem 命令进行提权,但如果提权没有成功,你就准备认输了吗?只有懦夫才会认输.但是你不是,对吗?你是一个勇者! ...
- 2018-2019-2 20162318《网络对抗技术》Exp3 免杀原理与实践
一.实验内容 1.正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil-evasion),加壳工具),使用shellcode编程 2.通过组合应用各种技术实现恶意代码免杀(如果成 ...
- 【对比分析五】CSS阻塞和JS阻塞
js 的阻塞特性: 所有浏览器在下载 JS 的时候,会阻止一切其他活动,比如其他资源的下载,内容的呈现等等.直到 JS 下载.解析.执行完毕后才开始继续并行下载其他资源并呈现内容.为了提高用户体验,新 ...
- Codeforces Round #296 (Div. 1) C. Data Center Drama 欧拉回路
Codeforces Round #296 (Div. 1)C. Data Center Drama Time Limit: 2 Sec Memory Limit: 256 MBSubmit: xx ...
- C# 7.0特性与vs2017
下面是关于在C#7.0语言中计划功能的说明.其中大部分功能在Visual Studio “15” Preview 4中能运行.现在是最好的试用时期,请记录下你们的想法. C#7.0语言增加了许多的新功 ...
- django源码(2.0.2)粗解之命令行执行
前言 django的命令行在整个的django web开发中都会经常用到,而且是必须得用到.所以,能够了解下django的命令行实现其实是非常有帮助的. 如果大家比较关心django命令的详细说明和使 ...
- ThinkPHP中I('post.')与create()方法的对比
简要归纳: 1.二者都可用来接收post表单提交的数据. 2.I('post.')方法可直接接收赋值给变量如$post=I('post.'),create()方法源于父类模型封装,需先实例化父类模型, ...
- 【scrapy】使用方法概要(一)(转)
[请初学者作为参考,不建议高手看这个浪费时间] 工作中经常会有这种需求,需要抓取互联网上的数据.笔者就经常遇到这种需求,一般情况下会临时写个抓取程序,但是每次遇到这种需求的时候,都几乎要重头写,特别是 ...
- FT项目开发技术点(二)
1.mybatis二级缓存,指的的是将数据缓存,而非对象,而非获得的list.缓存将数据库中的数据,是数据,缓存到内存中.之后将数据每次重新加载到list中,所以每次生成的list对象都是不同的,li ...
- 技术交流:DDD在企业开发的案例分享
背景 因为工作上的原因,这次技术交流准备的不够充分,晚上通宵写的演示代码,不过整个过程还是收获蛮大的,具体如下: 对原子操作有了更深入的了解,自己写的无锁循环队列(有点类似 RingBuffer)终于 ...