数据存储之CoreData(基础)

ios开发常用的五种数据存储方式:

  • plist
  • NSUserDefaults
  • NSKeyedArchiver
  • FMDB
  • CoreData

这篇文章我们主要回顾Core Data的使用

Core Data

因为Core data涉及到的东西较多,在这里先写一些入门的操作(多表关联以后会更新)
core data涉及到的一些类:

 (1)NSManagedObjectContext(被管理的数据上下文)
    操作实际内容(操作持久层)
    作用:插入数据,查询数据,删除数据
 (2)NSManagedObjectModel(被管理的数据模型)
    数据库所有表格或数据结构,包含各实体的定义信息
    作用:添加实体的属性,建立属性之间的关系
    操作方法:视图编辑器,或代码
 (3)NSPersistentStoreCoordinator(持久化存储助理)
    相当于数据库的连接器
    作用:设置数据存储的名字,位置,存储方式,和存储时机
 (4)NSManagedObject(被管理的数据记录)
    相当于数据库中的表格记录
 (5)NSFetchRequest(获取数据的请求)
    相当于查询语句
 (6)NSEntityDescription(实体结构)
    相当于表格结构,NSEntityDescription对象包含了Entity所拥有的属性,关系等信息,我们可以通过NSEntityDescription生成相应的NSManagedObject的实体

coredata的使用

1.创建coreDataDemo 如图选中User Core Data


数据存储之CoreData(基础)_第1张图片
90FF46FE-6465-49C2-9FD7-3CDAA95D6855.png

“Use Core Data”这个勾给我们做了些额外的工作,一是将“CoreData.framework”增加到我们工程的Frameworks列表中来了,二是在AppDelegate中增加了一些关于CoreData的代码.
如果你的工程没勾选“Use Core Data”这个选项,你也可以模仿一个新创建的“Use Core Data”的工程把必要的代码添加上去,完全没问题.
选中


屏幕快照 2016-11-29 下午8.57.28.png

2.添加实体
数据存储之CoreData(基础)_第2张图片
53464188-A7E9-46C4-B46D-2FBF96C0C8B9.png

3.然后新建一个file,记得是NSManagedObject cubclass

数据存储之CoreData(基础)_第3张图片
5556A2E1-D835-4007-AC99-72A6CD50DF3F.png
数据存储之CoreData(基础)_第4张图片
0E3675FA-EC3C-47A5-8391-9B9C5E01D3D9.png
数据存储之CoreData(基础)_第5张图片
BA7400A0-AEFB-4114-9726-FC643F3121B1.png

生成四个文件(ios7之前是两个)

数据存储之CoreData(基础)_第6张图片
屏幕快照 2016-11-30 下午12.40.07.png

4.代码示例

下面我们建立一个单例来演示coredate的 增、删、改、查功能

(1) 增

//增
-(BOOL)saveCarInfoByCarModel:(CarModel *)carmodel
{
    BOOL retVal = NO;
    //NSManagedObjectContext(被管理的数据上下文),操作实际内容(操作持久层)作用:插入数据,查询数据,删除数据
    NSManagedObjectContext *context = [APPDELEGATE managedObjectContext];
    //下面代码相当于 alloc init 初始化
    Car *car = [NSEntityDescription insertNewObjectForEntityForName:@"Car" inManagedObjectContext:context];
    car.userID = carmodel.userID;
    car.carID = carmodel.carID;
    car.carName = carmodel.carName;
    car.carNumber = carmodel.carNumber;
    car.carIsDefault = carmodel.carIdDefault;
    NSError *error;
    if ([context save:&error]) {
        NSLog(@"保存成功");
        retVal = YES;
    }
    return retVal;
}


在VC中执行

-(void)insertAction
{
   CarModel *carmodel = [[CarModel alloc]init];
   carmodel.userID = @"2011";
   carmodel.carID = @"1dwdwq";
   carmodel.carName = @"兰博基尼";
   carmodel.carNumber = @"京A93459";
   carmodel.carIdDefault = @"0";
   if ([[SingleTon sharedSingleTon] saveCarInfoByCarModel:carmodel]) {
       NSLog(@"插入数据成功");
     }
}


在此之前我们需要在appdelegate中打印数据库的地址便于查看数据信息

数据存储之CoreData(基础)_第7张图片
F65A0799-062D-4FBF-80A1-3835F27AA2C1.png

运行结果如下:

2016-11-30 12:51:29.163 coreDataDemo[31612:1990693] file:///Users/x8f/Library/Developer/CoreSimulator/Devices/7A1AE587-2880-40CE-A11B-17F7DFE94ACD/data/Containers/Data/Application/D66488E1-0E5E-44F8-B75A-5C44DD5954CF/Documents/coreDataDemo.sqlite
2016-11-30 12:51:29.174 coreDataDemo[31612:1990693] 保存成功
2016-11-30 12:51:29.174 coreDataDemo[31612:1990693] 插入数据成功


前往-->前往文件夹-->输入数据库地址后看到:

屏幕快照 2016-11-30 下午12.53.26.png

使用SQLiteManager打开数据库文件
数据库下载地址: https://github.com/skyxian/SQLiteManager
数据存储之CoreData(基础)_第8张图片
屏幕快照 2016-11-30 下午12.53.50.png

数据存储之CoreData(基础)_第9张图片
屏幕快照 2016-11-30 下午12.54.12.png

数据添加成功 !
然后我们再多添加几个数据便于改、删、查的操作演示
我添加了六条数据如下:

数据存储之CoreData(基础)_第10张图片
1.02.33.png

(2) 删

//删:根据carID来删除carID对应的那个车辆
-(BOOL)deleteCarInfoByCarID:(NSString *)carID
{
   BOOL retVal = NO;
   NSManagedObjectContext *context = [APPDELEGATE managedObjectContext];
   //建立请求
   NSFetchRequest *request = [[NSFetchRequest alloc]init];
   //读取所有Car
   NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:context];
   request.entity = entity;
   //设置检索条件(不设则默认检索所有Car)
   NSPredicate *predicate = [NSPredicate predicateWithFormat:@"carID=%@",carID];
   request.predicate = predicate;
   NSError *error;
   NSArray *arr = [context executeFetchRequest:request error:&error];
   if (arr.count) {
       for (Car *car in arr) {
           //删除对象
           [context deleteObject:car];
       }
       //保存删除的结果
       if ([context save:nil]) {
           retVal = YES;
       }
   }else{
       NSLog(@"没有检索到对象");
   }
   return retVal;
}


VC中我们执行 删除carID = @"e28r22"的那个car对象的操作

-(void)deleteAction
{
   CarModel *carmodel = [[CarModel alloc]init];
   carmodel.carID = @"e28r22";
   if ([[SingleTon sharedSingleTon] deleteCarInfoByCarID:carmodel.carID]) {
      NSLog(@"删除数据成功");
   }
}


打印结果如下:

2016-11-30 13:15:33.410 coreDataDemo[31862:2004730] file:///Users/x8f/Library/Developer/CoreSimulator/Devices/7A1AE587-2880-40CE-A11B-17F7DFE94ACD/data/Containers/Data/Application/6A977C79-3A51-449D-8D5E-EF5F8009D2EA/Documents/coreDataDemo.sqlite
2016-11-30 13:15:33.417 coreDataDemo[31862:2004730] 删除数据成功


我们打开数据库查看

数据存储之CoreData(基础)_第11张图片
1.18.15.png

carID为@"e28r22"的那个car对象被我们成功删除!

(3) 改

由上图我们看到数据库还有5条数据,现在我们修改userid为2012 carid为r3nkr3 的数据信息(coredata中使用&&连接符)

//改:根据userID以及carID来修改车辆信息
-(BOOL)updateCarInfoByCarModel:(CarModel *)carmodel
{
    BOOL retVal = NO;
    NSManagedObjectContext *context = [APPDELEGATE managedObjectContext];
    //建立请求
    NSFetchRequest *request = [[NSFetchRequest alloc]init];
    //读取所有Car
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:context];
    request.entity = entity;
    //设置检索条件(不设则默认检索所有Car)
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"userID = %@ && carID = %@",carmodel.userID,carmodel.carID];
    request.predicate = predicate;
    NSError *error;
    NSArray *arr = [context executeFetchRequest:request error:&error];
    if (arr.count) {
        for (Car *car in arr) {
            car.userID = carmodel.userID;
            car.carID = carmodel.carID;
            car.carIsDefault = carmodel.carIdDefault;
            car.carName = carmodel.carName;
            car.carNumber = carmodel.carNumber;
            if ([context save:nil]) {
                retVal = YES;
            }
        }
    }else{
        NSLog(@"没有检索到对象");
      }
    return retVal;
}


在VC中执行

-(void)updateAction
{
   CarModel *carmodel = [[CarModel alloc]init];
   carmodel.userID = @"2012";
   carmodel.carID = @"r3nkr3";
   carmodel.carName = @"路虎";
   carmodel.carNumber = @"京A80808";
   carmodel.carIdDefault = @"1";
   if ([[SingleTon sharedSingleTon] updateCarInfoByCarModel:carmodel]) {
       NSLog(@"更新数据成功");
   }
}


去数据库查看

数据存储之CoreData(基础)_第12张图片
BCB302D6-83F6-4410-9DAC-5DA5EA91D8A1.png

userid为2012 carid为r3nkr3 的数据被成功修改

(4) 查

我们来查找所有userid为2010的车辆信息

// 查:根据userID查寻该userID对应的所有车辆
-(NSArray *)queryCarInfoByUserID:(NSString *)userID
{
   NSManagedObjectContext *context = [APPDELEGATE managedObjectContext];
   //建立请求
   NSFetchRequest *request = [[NSFetchRequest alloc]init];
   //读取所有Car
   NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:context];
   request.entity = entity;
   //设置检索条件(不设则默认检索所有Car)
   NSPredicate *predicate = [NSPredicate predicateWithFormat:@"userID = %@",userID];
   request.predicate = predicate;
   NSError *error;
   NSMutableArray *listArr = [NSMutableArray new];
   NSArray *arr = [context executeFetchRequest:request error:&error];
   for (Car *car in arr) {
       CarModel *model = [[CarModel alloc]init];
       model.userID = car.userID;
       model.carID = car.carID;
       model.carIdDefault = car.carIsDefault;
       model.carName = car.carName;
       model.carNumber = car.carNumber;
       [listArr addObject:model];
   }
   return listArr;
}   


VC中执行

-(void)queryAction
{
   CarModel *carmodel = [[CarModel alloc]init];
   carmodel.userID = @"2010";
   NSArray *arr = [[SingleTon sharedSingleTon]queryCarInfoByUserID:carmodel.userID];
   if (arr) {
     for (CarModel *model in arr) {
         NSLog(@"%@---%@---%@---%@---%@",model.userID,model.carID,model.carName,model.carNumber,model.carIdDefault);
     }
   }
}


打印结果如下

2016-11-30 13:35:24.914 coreDataDemo[31986:2016010] file:///Users/x8f/Library/Developer/CoreSimulator/Devices/7A1AE587-2880-40CE-A11B-17F7DFE94ACD/data/Containers/Data/Application/99FCBB9B-41BD-460F-BF23-7231126FDFC4/Documents/coreDataDemo.sqlite
2016-11-30 13:35:24.919 coreDataDemo[31986:2016010] 2010---29eh4f---法拉利---京A429e8---1
2016-11-30 13:35:24.919 coreDataDemo[31986:2016010] 2010---bi3k1---大众---京A82eb2---0
2016-11-30 13:35:24.919 coreDataDemo[31986:2016010] 2010---9d20d2---蒙迪欧---京A11111---0


查询成功 !

数据迁移

假设存在这样一个场景,car这个实体现有的属性字段已经无法满足我们的需求,需要给它添加几个字段并修改原有的部分字段,这个时候我们就需要使用数据迁移了,否则程序会crash!
ok !我们在本demo中继续演示 版本迁移
(1) 选中你的coreDataDemo.xcdatamodeld文件,选择Xcode菜单editor->Add Model Version
比如取名:coreDataDemo 2.xcdatamodel

数据存储之CoreData(基础)_第13张图片
屏幕快照 2016-11-30 下午2.25.21.png
数据存储之CoreData(基础)_第14张图片
1628981F-4EEC-4084-BBCE-56FEC8D70CE9.png

这个时候你会发现CoreData.xcdatamodeld中多了一个版本文件,如图:

数据存储之CoreData(基础)_第15张图片
屏幕快照 2016-11-30 下午2.39.05.png

(2) 选择刚才创建的版本,在inspector中的Versioned Core Data Model选择Current模版为coreDataDemo 2.xcdatamodel


数据存储之CoreData(基础)_第16张图片
451AC5F8-650F-4D14-9971-8B88CE127F9D.png

(3) 修改新数据模型coreDataDemo 2,在新的文件上添加属性字段和修改实体 ( 切记!!!是在新的coreDataDemo 2上添加及修改属性)

数据存储之CoreData(基础)_第17张图片
9326245E-F836-4E78-AAEB-5C1376ABBFBC.png

(4) 修改原来的实体文件(或者删除原来的实体文件,重新生成新的实体下的类)

数据存储之CoreData(基础)_第18张图片
C38126DA-403D-4EC3-A6C1-F3F69D00DE20.png
数据存储之CoreData(基础)_第19张图片
1CF7413C-187E-431B-BC84-AD22EFC67730.png

(5)在AppDelegate.m的persistentStoreCoordinator中添加代码:

数据存储之CoreData(基础)_第20张图片
758E84FB-E3E8-4DBC-A74C-EFB22D63EFC9.png

运行--成功 !
现在我们再次向数据库中添加一条数据看看有什么效果

-(void)insertAction
{
    /*
     *
     *  这里最好多添加几条数据便于后面 删、改、查 的操作演示
     *
     */
    CarModel *carmodel = [[CarModel alloc]init];
    carmodel.userID = @"2013";
    carmodel.carID = @"8f3hf3";
    carmodel.carName = @"法拉利";
    carmodel.carNumber = @"京A86868";
    carmodel.carIdDefault = @"0";
    if ([[SingleTon sharedSingleTon] saveCarInfoByCarModel:carmodel]) {
        NSLog(@"插入数据成功");
    }
}


打印结果:

2016-11-30 15:02:35.063 coreDataDemo[32513:2055137] file:///Users/x8f/Library/Developer/CoreSimulator/Devices/7A1AE587-2880-40CE-A11B-17F7DFE94ACD/data/Containers/Data/Application/EF713FA9-E1D0-4E42-BC6A-CBBF438AB4A9/Documents/coreDataDemo.sqlite
2016-11-30 15:02:35.136 coreDataDemo[32513:2055137] 保存成功
2016-11-30 15:02:35.136 coreDataDemo[32513:2055137] 插入数据成功


进入数据库查看

数据存储之CoreData(基础)_第21张图片
05AA1904-6652-4518-8DB1-32DE310443CD.png

数据添加成功,且数据库中多了一个carDistance的字段,说明数据迁移成功!

demo地址:https://github.com/skyxian/coreDataDemo

你可能感兴趣的:(数据存储之CoreData(基础))