-
配置
-
1、在工程中新建 Data Model 数据模型文件。
![CoreData3]()
![CoreData4]()
-
2、在 Data Model 模型文件中添加 Entity 实体,修改实体名称,并在实体中添加模型属性。
![CoreData5]()
-
3、在模型文件右侧属性列表的 Code Generation 中设置生成 NSManagedObject subclass 子类的使用语言。
![CoreData6]()
-
4、在模型文件右侧属性列表的 Class => Codegen 中设置 Manual/None。如果不修改此项程序编译时会报 Linker command failed with exit code 1 (use -v to see invocation) 错误。
![CoreData7]()
-
5、基于 Data Model 数据库文件中的 Entity 创建 NSManagedObject subclass 类。Xcode8 从系统菜单的 Editor 创建,创建后文件中多出来 4 个文件。
![CoreData8]()
![CoreData9]()
![CoreData10]()
![CoreData11]()
-
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];
}
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 类。
![CoreData12]()
![CoreData13]()
-
在使用的文件中引入头文件
// 添加宏定义
#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];