Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象。在此数据操作期间,我们不需要编写任何SQL语句,这个有点类似于著名的Hibernate持久化框架,不过功能肯定是没有Hibernate强大的。简单地用下图描述下它的作用:
左边是关系模型,即数据库,数据库里面有张person表,person表里面有id、name、age三个字段,而且有2条记录;
右边是对象模型,可以看到,有2个OC对象;
利用Core Data框架,我们就可以轻松地将数据库里面的2条记录转换成2个OC对象,也可以轻松地将2个OC对象保存到数据库中,变成2条表记录,而且不用写一条SQL语句。
在Core Data,需要进行映射的对象称为实体(entity),而且需要使用Core Data的模型文件来描述app中的所有实体和实体属性。这里以Department(部门)和Employee(员工)2个实体为例子,先看看实体属性和实体之间的关联关系:
Employee实体中有:name(姓名)、age(年龄)、height(身高)三个属性
Department实体中有:departmentName(部门名称)、departmentNo(编号)两个属性
接下来看看创建模型文件的过程:
1.选择模板,名称随意2.添加实体
3.添加Department的2个基本属性
4.添加Card的1个基本属性
5.建立Card和Person的关联关系
Employee中有个Department类型的Department属性,目的就是建立Employee跟Department之间的一对一关联关系(建议补上这一项),在Department中加上Inverse属性后,你会发现Person中Inverse属性也自动补上了
设置关系的一对多或者一对一
1.通过Core Data从数据库取出的对象,默认情况下都是NSManagedObject对象
2.NSManagedObject的工作模式有点类似于NSDictionary对象,通过键-值对来存取所有的实体属性
1> setValue:forKey:存储属性值(属性名为key)
2> valueForKey:获取属性值(属性名为key)
注:黑色表示类名,红色表示类里面的一个属性
开发步骤总结:
1.初始化NSManagedObjectModel对象,加载模型文件,读取app中的所有实体信息
2.初始化NSPersistentStoreCoordinator对象,添加持久化库(这里采取SQLite数据库)
3.初始化NSManagedObjectContext对象,拿到这个上下文对象操作实体,进行CRUD操作
默认情况下,利用Core Data取出的实体都是NSManagedObject类型的,能够利用键-值对来存取数据。但是一般情况下,实体在存取数据的基础上,有时还需要添加一些业务方法来完成一些其他任务,那么就必须创建NSManagedObject的子类
选择模型文件
选择需要创建子类的实体
创建完毕后,多了2个子类
文件内容展示:
Employee.h
#import <Foundation/Foundation.h> #import <CoreData/CoreData.h> @class Department; @interface Employee : NSManagedObject @property (nonatomic, retain) NSString * name; @property (nonatomic, retain) NSNumber * age; @property (nonatomic, retain) NSNumber * height; @property (nonatomic, retain) Department *mydepartment; @end
Employee.m
#import "Employee.h" #import "Department.h" @implementation Employee @dynamic name; @dynamic age; @dynamic height; @dynamic mydepartment; @end
Department.h
#import <Foundation/Foundation.h> #import <CoreData/CoreData.h> @class Employee; @interface Department : NSManagedObject @property (nonatomic, retain) NSNumber * departmentNo; @property (nonatomic, retain) NSString * departmentName; @property (nonatomic, retain) NSSet *myemployee; @end @interface Department (CoreDataGeneratedAccessors) - (void)addMyemployeeObject:(Employee *)value; - (void)removeMyemployeeObject:(Employee *)value; - (void)addMyemployee:(NSSet *)values; - (void)removeMyemployee:(NSSet *)values; @end
Department.m
#import "Department.h" #import "Employee.h" @implementation Department @dynamic departmentNo; @dynamic departmentName; @dynamic myemployee; @end
1.搭建上下文环境
//初始化上下文 NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init]; self.context = context; //根据资源来获取模型文件 NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"Company" withExtension:@"momd"]]; //通过模型文件初始化助理 NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; //存放数据位置 NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]; NSString *sqlitePath = [docPath stringByAppendingPathComponent:@"company.sqlite"]; NSLog(@"%@", sqlitePath); //关联前的准备\ 1:存储类型(SQLite)\ 2:存放位置(Document) [store addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:sqlitePath] options:nil error:nil]; //创建一个数据持久化助理来关联模型文件 context.persistentStoreCoordinator = store;
2.添加数据到数据库
/* for (int i = 0; i<20; i++) { //通过实体描述来创建模型对象 Employee *emps = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:self.context]; emps.name = [NSString stringWithFormat:@"BJS1507%.2d",i]; emps.age = [NSNumber numberWithInt:arc4random() %20+40]; emps.height = @160.9; [self.context save:nil]; } */ Employee *zhangsan = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:self.context]; zhangsan.name = @"张三"; zhangsan.age = @32; zhangsan.height = @182; Employee *lisi = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:self.context]; lisi.name = @"李四"; lisi.age = @22; lisi.height = @82; Employee *wangwu = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:self.context]; wangwu.name = @"王五"; wangwu.age = @22; wangwu.height = @162; //部门 Department *ios = [NSEntityDescription insertNewObjectForEntityForName:@"Department" inManagedObjectContext:self.context]; ios.departmentName = @"ios"; ios.departmentNo = @1000; Department *android = [NSEntityDescription insertNewObjectForEntityForName:@"Department" inManagedObjectContext:self.context]; android.departmentName = @"android"; android.departmentNo = @1001; //给公司添加员工 /* //添加多个员工 [ios addMyemployee:[NSSet setWithObjects:lisi, zhangsan, nil]]; //添加单个员工 // [android addMyemployeeObject:wangwu]; */ //给员工添加公司 zhangsan.mydepartment = ios; lisi.mydepartment = ios; wangwu.mydepartment = android; [self.context save:nil];
3.从数据库中查询/更新数据
//获取 请求 NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"]; //谓词查询 //"="查询绝对的字段, // request.predicate = [NSPredicate predicateWithFormat:@"name = %@",@"BJS150715"]; //模糊查询 "CONTAINS" 包含 // request.predicate = [NSPredicate predicateWithFormat:@"age CONTAINS %@", @"2"]; //模糊查询"LIKE" *在字段前面代表查询后边包含该字段的数据 //*在字段后面反之 // request.predicate = [NSPredicate predicateWithFormat:@"name like %@", @"*5*"]; //排序 request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES]]; //执行查找请求 NSArray *array = [self.context executeFetchRequest:request error:nil]; for (Employee *emps in array) { NSLog(@"name = %@ age = %@ height = %@", emps.name, emps.age, emps.height); //更新操作,直接在此更新属性即可 emps.name = @"二货啊"; }
注:Core Data不会根据实体中的关联关系立即获取相应的关联对象,比如通过Core Data取出Person实体时,并不会立即查询相关联的Card实体;当应用真的需要使用Card时,才会再次查询数据库,加载Card实体的信息。这个就是Core Data的延迟加载机制
4.删除数据库中的数据
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"]; request.predicate = [NSPredicate predicateWithFormat:@"name contains %@", @"BJS"]; NSArray *array = [self.context executeFetchRequest:request error:nil]; for (Employee *emps in array) { [self.context deleteObject:emps]; } [self.context save:nil];
1.打开Product,点击EditScheme...
2.点击Arguments,在ArgumentsPassed On Launch中添加2项
1> -com.apple.CoreData.SQLDebug
2> 1
说到这里,整个Core Data框架的入门就结束了,其实Core Data还远不止这些功能,它还支持自动撤销机制,一对多关联等,这里就不一一介绍了