Core Data

简介

  Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象。在此数据操作期间,我们不需要编写任何SQL语句,这个有点类似于著名的Hibernate持久化框架,不过功能肯定是没有Hibernate强大的。简单地用下图描述下它的作用:

Core Data_第1张图片

左边是关系模型,即数据库,数据库里面有张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.选择模板,名称随意
Core Data_第2张图片Core Data_第3张图片2.添加实体
Core Data_第4张图片

3.添加Department的2个基本属性

Core Data_第5张图片

4.添加Card的1个基本属性
Core Data_第6张图片


5.建立Card和Person的关联关系

Core Data_第7张图片

Core Data_第8张图片        

    Employee中有个Department类型的Department属性,目的就是建立Employee跟Department之间的一对一关联关系(建议补上这一项),在Department中加上Inverse属性后,你会发现Person中Inverse属性也自动补上了

Core Data_第9张图片

设置关系的一对多或者一对一


了解NSManagedObject

1.通过Core Data从数据库取出的对象,默认情况下都是NSManagedObject对象
Core Data_第10张图片

2.NSManagedObject的工作模式有点类似于NSDictionary对象,通过键-值对来存取所有的实体属性

1> setValue:forKey:存储属性值(属性名为key)

2> valueForKey:获取属性值(属性名为key)


CoreData中的核心对象


Core Data_第11张图片
注:黑色表示类名,红色表示类里面的一个属性
发步骤总结:
1.初始化NSManagedObjectModel对象,加载模型文件,读取app中的所有实体信息
2.初始化NSPersistentStoreCoordinator对象,添加持久化库(这里采取SQLite数据库)
3.初始化NSManagedObjectContext对象,拿到这个上下文对象操作实体,进行CRUD操


创建NSManagedObject的子类

默认情况下,利用Core Data取出的实体都是NSManagedObject类型的,能够利用键-值对来存取数据。但是一般情况下,实体在存取数据的基础上,有时还需要添加一些业务方法来完成一些其他任务,那么就必须创建NSManagedObject的子类
Core Data_第12张图片

选择模型文件 
Core Data_第13张图片

选择需要创建子类的实体 
Core Data_第14张图片

创建完毕后,多了2个子类 
Core Data_第15张图片

文件内容展示:
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];


打开CoreData的SQL语句输出开关

1.打开Product,点击EditScheme...
2.点击Arguments,在ArgumentsPassed On Launch中添加2项
1> -com.apple.CoreData.SQLDebug
2> 1

Core Data_第16张图片Core Data_第17张图片




说到这里,整个Core Data框架的入门就结束了,其实Core Data还远不止这些功能,它还支持自动撤销机制,一对多关联等,这里就不一一介绍了


你可能感兴趣的:(Core Data)