1、CoreData 数据库

  • CoreData 是 iOS SDK 里的一个很强大的框架,允许程序员以面向对象的方式储存和管理数据。使用 CoreData 框架,程序员可以很轻松有效地通过面向对象的接口管理数据。CoreData 框架提供了 对象 - 关系映射 (ORM) 的功能,即能够将 OC 对象转化成数据,保存在 SQLite3 数据库文件中,也能够将保存在数据库中的数据还原成 OC 对象,在数据操作过程中,无需编写任何 SQL 语句。

  • 模型文件及实体(Entity)。要使用 CodeData,首先需要定义模型文件,描述应用程序中的所有实体(Entities),所谓实体是跟数据库进行映射的对象。

  • NSManagedObject:对应数据库中的一条记录。

  • CoreData 主要对象关系示意图类似于数据库的句柄,handle,用来操纵数据库 持久化存储调度者,是数据库与对象之间的,在开发中。只会用到一次,如果不理解,直接粘代码。

  • CoreData 主要对象

    • NSManagedObjectContext:负责应用和数据库之间的交互 (CRUD)。

    • NSPersistentStoreCoordinator:添加持久化存储库(如 SQLite 数据库), 是物理数据存储的物理文件和程序之间的联系的桥梁 ,负责管理不同对象上下文。

    • NSManagedObjectModel:被管理的对象模型。

    • NSEntityDescription:实体描述。

2、CoreData 的使用

  • 配置

    • 1、在工程中新建 Data Model 数据模型文件。

    • 2、在 Data Model 模型文件中添加 Entity 实体,修改实体名称,并在实体中添加模型属性。

    • 3、在模型文件右侧属性列表的 Code Generation 中设置生成 NSManagedObject subclass 子类的使用语言。

    • 4、在模型文件右侧属性列表的 Class => Codegen 中设置 Manual/None。如果不修改此项程序编译时会报 Linker command failed with exit code 1 (use -v to see invocation) 错误。

    • 5、基于 Data Model 数据库文件中的 Entity 创建 NSManagedObject subclass 类。Xcode8 从系统菜单的 Editor 创建,创建后文件中多出来 4 个文件。

    • 6、在需要使用 CoreData 的文件中。

      	// 引入头文件
      #import "Student+CoreDataClass.h" // 宏定义实体(数据表)名称
      #define ENTITY_STUDENT @"Student"
  • 搭建 CoreData 环境

    	// 声明目标对象上下文,CoreData 操作数据的环境
    @property (nonatomic, strong) NSManagedObjectContext *moc; // 托管对象模型文件路径
    NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"TestModel" ofType:@"momd"];
    NSURL *modelUrl = [NSURL fileURLWithPath:modelPath]; // 创建托管对象模型,CoreData 数据模型文件
    NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelUrl]; // 创建持久化存储协调器,处理数据的读写
    NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; // SQLite 数据库文件路径,CoreData 使用的数据库文件后缀一般写 sqlite
    NSString *sqlPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject
    stringByAppendingPathComponent:@"student.sqlite"];
    NSURL *sqlUrl = [NSURL fileURLWithPath:sqlPath]; NSLog(@"sqlPath:%@", sqlPath); // 将 CoreData 文件映射到数据库,并判断操作状态
    NSError *error = nil; NSPersistentStore *store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType
    configuration:nil URL:sqlUrl options:nil error:&error]; if (!store) {
    NSLog(@"addError = %@", error);
    } // 创建操作数据的对象
    self.moc = [[NSManagedObjectContext alloc] init]; // 关联持久化存储协调器
    self.moc.persistentStoreCoordinator = coordinator;
  • 插入数据

    	// 获取插入到实体的指针
    Student *std = [NSEntityDescription insertNewObjectForEntityForName:ENTITY_STUDENT inManagedObjectContext:self.moc]; // 赋值
    std.name = self.nameTF.text;
    std.age = self.ageTF.text.intValue; NSError *error = nil; // 同步到数据库并判断
    if ([self.moc save:&error]) { [self.myDataArray addObject:std];
    [self.myTableView reloadData];
    } else { NSLog(@"insert error = %@", error);
    }
  • 删除数据

    	// 获取要删除的数据
    Student *std = self.myDataArray[self.selectedRow]; // 从实体中删除
    [self.moc deleteObject:std]; NSError *error = nil; // 同步到数据库并判断
    if ([self.moc save:&error]) { [self.myDataArray removeObjectAtIndex:self.selectedRow];
    [self.myTableView reloadData];
    } else { NSLog(@"delete error = %@", error);
    }
  • 修改数据

    	// 获取要修改的数据
    Student *dent = self.myDataArray[self.selectedRow]; // 赋值
    dent.name = self.nameTF.text;
    dent.age = self.ageTF.text.intValue; NSError *error = nil; // 同步到数据库并判断
    if ([self.moc save:&error]) { [self.myTableView reloadData];
    } else { NSLog(@"update error = %@", error);
    }
  • 查询数据

    	// 查询请求
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:ENTITY_STUDENT]; // 查询条件(正则表达式),name 以某些字符开头
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@",
    [NSString stringWithFormat:@"%@*", self.nameTF.text]]; // 设置请求条件,如果不设查询条件会查询所有
    request.predicate = predicate; NSError *error = nil; // 执行查询
    self.myDataArray.array = [self.moc executeFetchRequest:request error:&error]; if (error) { NSLog(@"fech = %@", error);
    } else { [self.myTableView reloadData];
    }
    	// 查询所有 CoreData 数据
    
    	// 查询请求
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:ENTITY_STUDENT]; NSError *error = nil; // 查询
    NSArray *tmpArray = [self.moc executeFetchRequest:request error:&error]; if (error) { NSLog(@"fech = %@", error);
    } else { // 将查询结果存储到数据源数组中
    [self.myDataArray setArray:tmpArray];
    [self.myTableView reloadData];
    }

3、MagicalRecord 的使用

  • CoreData 是 iOS 开发中经常使用的数据持久化的技术。但其操作过程稍微繁琐,即使你只是实现简单的存取,不涉及请求优化,也要进行许多配置工作,代码量在动辄几十行,对新手来说也需要较大时间成本。

  • MagicalRecord 是 OC 的一个库,协助方便 CoreData 的工作。其吸收了 Ruby on Rails 的 Active Record 模式,目标是:

    • 简化 Core Data 相关代码
    • 允许清晰,简单,单行获取
    • 当需要优化请求的时候,仍然允许修改 NSFetchRequest
  • 如果你在使用 MagicalRecord 方法的时候不想带 MR_ 前缀,直接用 findAll 代替 MR_findAll,就在引入头文件 CoreData+MagicalRecord.h 之前增加 #define MR_SHORTHAND 即可。

  • 配置

    • 创建 Model。创建一个 Model.xcdatamodeld ,添加一个 Person Entity,添加 age firstname lastname 三个属性。最后使用 Editor => Create NSManagedObject Subclass ORM 生成 Person 类。

    • 在使用的文件中引入头文件

      	// 添加宏定义
      #define MR_SHORTHAND // 引入头文件
      #import "MagicalRecord.h"
  • 初始化

    	- (void)viewDidLoad {
    [super viewDidLoad]; // 初始化
    [MagicalRecord setupCoreDataStackWithStoreNamed:@"Model.sqlite"];
    } - (void)dealloc { // 清理
    [MagicalRecord cleanUp];
    }
  • 	Person *person = [Person MR_createEntity];
    
    	person.firstname = @"Frank";
    person.lastname = @"Zhang";
    person.age = 26; [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
  • 	Person *person = ...;       // 此处略,取出的数据模型
    
    	[person MR_deleteEntity];
    
    	[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
  • 	Person *person = ...;       // 此处略,取出的数据模型
    
    	person.lastname = object;
    
    	[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
  • 	// 查找数据库中的所有 Person。
    NSArray *persons = [Person MR_findAll]; // 查找所有的 Person 并按照 first name 排序。
    NSArray *personsSorted = [Person MR_findAllSortedBy:@"firstname" ascending:YES]; // 查找所有 age 属性为 25 的 Person 记录。
    NSArray *personsAgeEuqals25 = [Person MR_findByAttribute:@"age" withValue:[NSNumber numberWithInt:25]]; // 查找数据库中的第一条记录
    Person *person = [Person MR_findFirst];

iOS - CoreData 数据库存储的更多相关文章

  1. iOS:CoreData数据库的使用四(数据库和UITableViewController以及NSFetchedResultsController一起使用)

    CoreData数据库虽然可以和tableview或者UITableViewController一起使用将数据显示在表格上,但是在准备数据的时候,这种方式需要用一个可变数组来装从数据库一次性取出来的所 ...

  2. iOS:CoreData数据库的使用三(数据库和tableView表格一起使用)

    CoreData数据库是用来持久性存储数据的,那么,我们再从该数据库中取出数据干什么呢?明显的是为了对数据做操作,这个过程中可以将它们直观的显示出来,即通过表格的形式显示出来.CoreData配合ta ...

  3. iOS:CoreData数据库的使用一(创建单个数据库表)

    CoreData数据库框架:mac系统自带的数据库,它是苹果公司对sqlite进行封装而来的,既提供了对数据库的主要操作,也提供了具体的视图关系模型. 需要用到三个对象: 1•Managed Obje ...

  4. iOS coredata 数据库升级 时报Can't find model for source store

    在coredata 数据库结构被更改后,没根据要求立即建立新version,而是在原version上进行了小修改,之后才想起来建立新版本.并通过以下代码合并数据库, NSError *error = ...

  5. iOS基本数据库存储方式 - CoreData

    CoreData 创建模型文件的过程 1.选择模板 2.添加实体 3.添加实体的属性[注意]属性的首字母必须小写 一.CoreData管理类(必备以下三个类对象) 1.CoreData数据操作的上下文 ...

  6. iOS - SQLite 数据库存储

    1.SQLite 数据库 SQLite 是一种轻型的嵌入式数据库,安卓和 iOS 开发使用的都是 SQLite 数据库.它占用资源非常低,在嵌入式设备中,可能需要几百 K 的内存数据就够了.他的处理速 ...

  7. 【转】iOS - SQLite 数据库存储

    本文目录 1.SQLite 数据库 2.iOS 自带 SQLite 的使用 3.fmdb 的使用 4.fmdb 多线程操作 5.其他 SQLite 的第三方封装库 回到顶部 1.SQLite 数据库 ...

  8. iOS coredata 数据库的加密(待研究)

    https://github.com/project-imas/encrypted-core-data 使用起来很方便,底层还是使用了SQLCipher,有时间要研究一下! 数据库的密码不能用固定字符 ...

  9. iOS CoreData 介绍和使用(以及一些注意事项)

    iOS CoreData介绍和使用(以及一些注意事项) 最近花了一点时间整理了一下CoreData,对于经常使用SQLite的我来说,用这个真的有点用不惯,个人觉得实在是没发现什么亮点,不喜勿喷啊.不 ...

随机推荐

  1. 2.3 C#的常量

    常量,顾名思义,就是不会改变的量. 我们平时书写的数字(比如3.14159).字符(比如Q).字符串(比如 谢谢),他们都是一些常量. 在使用这些常量的时候,有些常量很重要而且经常用到,比如圆周率3. ...

  2. Docker相关文档

    网上找到的一个入门级Docker学习笔记,写的不错,值得一看. 转自:http://www.open-open.com/lib/view/open1423703640748.html#articleH ...

  3. html5 webDatabase 存储中sql语句执行可嵌套使用

    html5 webDatabase 存储中sql语句执行可嵌套使用,代码如下: *); data.transaction(function(tx){ tx.executeSql("creat ...

  4. Material Design Lite,简洁惊艳的前端工具箱 之 交互组件。

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接, 博客地址为http://www.cnblogs.com/jasonnode/ . 网站上有对应 ...

  5. Infinite loop when using cookieless session ID on Azure

    If you use cookieless session ID and deploy them on Azure, you might get infinite loop when you quer ...

  6. 简单使用Apache POI

    Apache POI是一个纯Java编写用来操作Microsoft Office的框架,最常见的应用是让服务器后台按照特定的数据生成Excel表格提供给用户实用.前段时间因为项目的需要被大量使用,使用 ...

  7. [转]Linux进程间通信——使用消息队列

    点击此处阅读原文 另收藏作者ljianhui的专栏初学Linux 下面来说说如何使用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linu ...

  8. Bash:-3次错误输入退出脚本

    Limit_Condition() { let count++ ]];then echo "超过3次机会,自动关停脚本" exit fi Comfirm() { count= wh ...

  9. IOS 创建渐变图层

    代码如下 typedef enum { GradientLayerKindLeftRight = , GradientLayerKindUpDown, GradientLayerKindLBRT,// ...

  10. 利用反射+AOP,封装Basehandler

    AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点, ...