iOS进阶学习-CoreData
一、CoreData数据库框架的优势
1、CoreData数据持久化框架是Cocoa API的一部分,首次在iOS5版本的系统中出现,它允许按照实体-属性-值模型组织数据,并以XML、二进制文件或者SQLite数据文件的格式持久化数据。CoreData主要提供独享-关系映射(ORM)功能,把OC对象转化为数据保存到文件,也可以数据转化为OC对象。
2、CoreData数据库框架的优势:
- sqlite:
- 基于C接口需要使用sql语句,代码繁琐。
- 在处理大量数据时,表关系更直观。
- 在OC中不是可视化的。
- CoreData:
- 可视化,有undo/redo能力
- 可以实现多种文件格式NSSQLiteStoreType、NSBinaryStoreType、NSInMemoryStoreType、NSXMLStoreType
- 苹果官方API支持,与iOS结合更紧密。
二、CoreData数据库框架的核心对象
1、持久化存储和存储文件
- NSPersistentStore:持久化存储,是对实际文件的一种Object-C表示方式,一个被封装好的底层类,用于存储数据。
- 存储文件:用来存储和管理数据的文件,iOS支持4种存储类型。
2、被管理对象上下文
- NSManagedObjectContext:被管理对象上下文CoreData中用于操作和使用数据,负责应用和数据库之间的交互。
- 数据的保存需要NSManagedObjectContext进行save操作。
- 数据的查询需要NSManagedObjectContext进行executeFetchRequest操作(返回值是数组)CoreData提供的是对象关系映射,NSManagedObjectContext操作的都是NSManagedObject对象。
3、被管理对象相关类
- NSManagedObjectMode:被管理对象模型,管理多个对象。
- NSManagedObject:被管理对象,CoreData返回的数据模型,被管理的对象是根据实体描述生成的。
- NSEntityDescription:实体描述类,根据实体创建被管理对象。
- Entity:实体类,实体是对文件数据的描述。被管理对象表示实体,实体包含名称,属性(字段)和关系,实体的名称通常和被管理对象名一致。
4、数据查询
- NSFetchRequest:查询请求,可以做排序操作,也可以使用谓词。
- NSManagedObjectContext根据NSFetchRequest查询数据,以数组形式返回,数组中包含被管理对象(NSManagedObject)。
- NSSortDescriptor:排序操作。
三、CoreData数据库的简单操作
- 创建实体类与属性
- 切换可视化关系图
- CoreData上下文的创建
@interface ViewController () // 声明属性(管理对象上下文,sqlite中是声明一个存储路径的属性) @property (nonatomic, strong) NSManagedObjectContext *managedObjectContext; @end @implementation ViewController // 懒加载 - (NSManagedObjectContext *)managedObjectContext { // 因为在AppDelegaate中已经实现过了,所以在这里从AppDelegate中去获取 if (_managedObjectContext == nil) { // 获取AppDelegate对象,用系统的单例方法创建 AppDelegate *appDelegate = [UIApplication sharedApplication].delegate; _managedObjectContext = appDelegate.managedObjectContext; } return _managedObjectContext; }
- 系统封装好的CoreData方法
@synthesize managedObjectContext = _managedObjectContext; @synthesize managedObjectModel = _managedObjectModel; @synthesize persistentStoreCoordinator = _persistentStoreCoordinator; - (NSURL *)applicationDocumentsDirectory { // 打印CoreData的存储路径(sqlite的dbPath字符串路径)URL类型 return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; } #pragma mark - 获取管理对象 - (NSManagedObjectModel *)managedObjectModel { if (_managedObjectModel != nil) { return _managedObjectModel; } NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"UISenior_4_1CoreData" withExtension:@"momd"]; _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return _managedObjectModel; } #pragma mark - 数据库持久化协调器 - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (_persistentStoreCoordinator != nil) { return _persistentStoreCoordinator; } _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"UISenior_4_1CoreData.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: userInfo:dict]; NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return _persistentStoreCoordinator; } #pragma mark - 获取数据库上下文 - (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; }
- 添加数据
#pragma mark - 添加数据 - (void)addPerson { // 添加的步骤 // 1.创建person实体对象,然后告诉managedObjectContext,让他做好准备,将这个对象添加到数据库中 Person *per = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext]; // 2.给对象属性赋值 per.personName = @"MBBoy"; per.personGender = @"Unknow"; per.personAge = @; // 3.将per对象存入数据库 BOOL result = [_managedObjectContext save:nil]; // 4.判断是否插入成功 if (result) { NSLog(@"添加数据成功"); }else { NSLog(@"添加数据失败"); } }
- 更改数据
#pragma mark - 更改数据 - (void)updatePerson { // 1.实例化查询请求类 NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"]; // 2.设置查询条件 fetchRequest.predicate = [NSPredicate predicateWithFormat:@"personName = 'MBBoy'"]; // 3.由context根据更新条件的请求去具体进行更新操作 NSArray *resultArray = [_managedObjectContext executeFetchRequest:fetchRequest error:nil]; // 4.遍历搜索出来的结果 for (Person *per in resultArray) { per.personName = @"Root"; per.personGender = @"animal"; per.personAge = @; } BOOL result = [_managedObjectContext save:nil]; // 6.判断结果 if (result) { NSLog(@"更新数据成功"); }else { NSLog(@"更新数据失败"); } }
- 删除数据
#pragma mark - 删除数据 - (void)deletePerson { // 1.实体化请求类(查询) NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Person"]; // 2.找到删除的条件(根据什么进行删除)(NSPredicate) request.predicate = [NSPredicate predicateWithFormat:@"personName = 'MBBoy'"]; // 3.由context根据删除条件的请求去具体进行删除操作 NSArray *resultArray = [_managedObjectContext executeFetchRequest:request error:nil]; // 4.遍历搜索出来的结果 for (Person *per in resultArray) { // 删除查询到的相关的人 [_managedObjectContext deleteObject:per]; } // 5.进行删除结果的判断 BOOL result = [_managedObjectContext save:nil]; // 6.判断结果 if (result) { NSLog(@"删除数据成功"); }else { NSLog(@"删除数据失败"); } }
- 查询数据
#pragma mark - 查询相关信息 - (void)selectAllPerson { // 1.实例化查询请求 NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Person"]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"personName LIKE '*R*'"]; request.predicate = predicate; NSArray *resultArray = [_managedObjectContext executeFetchRequest:request error:nil]; for (Person *per in resultArray) { NSLog(@"name = %@, gender = %@, age = %@", per.personName, per.personGender, per.personAge); } }
四、CoreData数据库表关联操作
- 添加表关系
五、CoreData数据库数据的迁移
- CoreData支持随着App开发演进而带来的对象模型升级或修改的管理。模型的改变将导致不兼容(或不能打开)以前版本创建的存储。如果你要改变你的模型,你就必须要改变现有存储中的数据-即数据存储格式(storeformat)——即数据迁移(migration)
- 数据迁移的三个阶段:
- 创建基于源实例对象的目标实例对象;
- 重新建立联系;
- 验证与保存。
- 版本迁移操作图:
iOS进阶学习-CoreData的更多相关文章
- iOS进阶学习-数据库
一.数据库管理系统 1.SQL语言概述:SQL是Structured Query Language(结构化查询语言)的缩写.SQL是专为数据库而建立的操作命令集,是一种功能齐全的数据库语言. 2.常见 ...
- iOS进阶学习-数据处理之文件读写
一.沙盒机制 1.什么是沙盒? 每一个iOS应用程序都会为自己创建一个文件系统目录(文件夹),这个独立.封闭.安全的空间,叫做沙盒. 2.沙盒机制(SandBox) 沙盒是一种安全体系. 它规定了应用 ...
- iOS进阶学习笔记
熟练掌握C/C++/Objective-C/Swift语言: 熟悉Cocoa Touch(Foundation,UIKit).Objective-C中block,gcd,NSOperation等: 熟 ...
- PHP程序员进阶学习书籍参考指南
PHP程序员进阶学习书籍参考指南 @heiyeluren lastmodify: 2016/2/18 [初阶](基础知识及入门) 01. <PHP与MySQL程序设计(第4版)> ...
- 开源中国iOS客户端学习
开源中国iOS客户端学习 续写前言 <开源中国iOS客户端学习>续写前系列博客 http://blog.csdn.net/column/details/xfzl-kykhd.html ...
- 爱了!阿里大神最佳总结“Flutter进阶学习笔记”,理论与实战
前言 "小步快跑.快速迭代"的开发大环境下,"一套代码.多端运行"是很多开发团队的梦想,美团也一样.他们做了很多跨平台开发框架的尝试:React Native. ...
- IOS基础学习-2: UIButton
IOS基础学习-2: UIButton UIButton是一个标准的UIControl控件,UIKit提供了一组控件:UISwitch开关.UIButton按钮.UISegmentedContro ...
- Matlab 进阶学习记录
最近在看 Faster RCNN的Matlab code,发现很多matlab技巧,在此记录: 1. conf_proposal = proposal_config('image_means', ...
- iOS进阶_地图上定位的标志——大头针
一.添加大头针 地图使用的框架是MapKit 大头针走的是MKAnnotation协议 /* 注意:因为是满足协议MKAnnotation,所以没有MKAnnotation的系统大头针类,必须自定义大 ...
随机推荐
- table extraction
http://yz.mit.edu/papers/webtables-vldb08.pdf http://www.vldb.org/pvldb/vol4/p528-venetis.pdf Alon H ...
- linux Apache和php配置
今天安装Apache httpd web服务器,安装过程分为三部分: (1)./configure (2)make (3)make install (需要root权限) 我的apache 安装在/ho ...
- I/O系统,多线程、图形用户界面编程
多线程 进程与线程区别: 进程需要分配独立的内存空间:线程在同一内存空间中工作,可以共享同一块内存和系统资源 与Java相关的API: 1)Thread类 方法:start()启动: urn() : ...
- 解决Linq第一次调用存储过程时速度慢的问题
最近做项目,发现linq调用存储过程,第一次时会速度慢,但之后速度都很快,过一阵子又会慢一下,以实际的操作为例子: using (FruitDbDataContext dbo = new FruitD ...
- 【MVC】ASP.NET MVC中实现多个按钮提交的几种方法
有时候会遇到这种情况:在一个表单上需要多个按钮来完成不同的功能,比如一个简单的审批功能. 如果是用webform那不需要讨论,但asp.net mvc中一个表单只能提交到一个Action处理,相对比较 ...
- pcap文件格式及文件解析
第一部分:PCAP包文件格式 一 基本格式: 文件头 数据包头数据报数据包头数据报...... 二.文件头: 文件头结构体 sturct pcap_file_header { DWORD ...
- Hbase rest方式获取指定key范围内的值
代码如下: <?php class Monitor_Hbase{ private $rest_host = "http://10.99.90.39:8130/";//rest ...
- 高效率的全组合算法(Java版实现)
博客上看到的一个算法,用Java实现了一个 算法描述: 算法说明:当n大于2时,n个数的全组合一共有(2^n)-1种. 当对n个元素进行全组合的时候,可以用一个n位的二进制数表示取法. 1表示在该位取 ...
- [leetcode]_Maximum Depth of Binary Tree
第三道树的题目,我还是不会,我擦,怎么递归算法还是不能很好理解.看来还得好好研究下递归算法. 题目:求一棵树的最大深度. 思路:递归地求取左子树最大深度 和 右子树最大深度,返回较大值即为 整棵树的 ...
- HTML5 对于手机页面长按会粘贴复制的禁用 (解决方案)
解决方案: 直接在CSS 文件中添加下面的代码,就可以实现了在手机端禁止粘贴复制的功能: *{ -webkit-touch-callout:none; /*系统默认菜单被禁用*/ -we ...