• CoreData的简单使用(二)数据的增删改查,轻量级的版本迁移


    上一篇中我们已经使用CoreData创建了一个SQLite数据库

    CoreData的简单使用(一)数据库的创建

    现在对数据库进行数据的CRUD(增删改查)

       1.Data Model 的设置

      创建一个DataModel,取名CRUD.xcdatamodeld,添加Entity(Library和Book),添加属性,在Book中设置和Library的关联关系(一个Book可以存放在一个Library里)

      Book的属性和关联关系(选择Destination为Library,关系名称取名为library)注意区分大小写

    Library的属性:

    创建NSManagerObject subclass:

    2. 在viewController.m来进行CRUD,注意方法的调用下面代码都抽离成方法,对数据进行操作都要创建_context对象(调用creatSQLite方法)

         (1)导入头文件

            #import "Library.h"

        #import "Book.h"

        #import <CoreData/CoreData.h>

      (2)设置context属性,因为我们是利用context进行CRUD,所以把它设置成一个属性或者全局变量

    @interface ViewController ()
    
    @property (strong, nonatomic) NSManagedObjectContext *context;
    
    @end

      (3)创建数据库

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    - (void)creatSQLite
    {
        //1.创建NSManagedObjectModel对象
        NSURL *dataModelURL = [[NSBundle mainBundle] URLForResource:@"CRUD" withExtension:@"momd"];
        NSManagedObjectModel *dataModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:dataModelURL];
        
        //2.创建NSPersistentStoreCoordinator对象
        NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:dataModel];
           //设置数据库保存路径
        NSString *path = [NSHomeDirectory() stringByAppendingString:@"/Documents/CRUD.sqlite"];
        NSLog(@"%@",path);
         
           //注意这里不能用[NSURL URLWithString:<#(nonnull NSString *)#>];
        NSURL *pathURL = [NSURL fileURLWithPath:path];
           //配置库的类型为SQLite
        [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:pathURL options:nil error:nil];
         
        //3.创建_context并与psc进行关联
        _context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        _context.persistentStoreCoordinator = psc;
    }

           去沙盒里找到数据库,查看一下,成功创建,关联关系也已经建立好了,Book里有一个LIBRARY的属性

       

    3.添加数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    - (void)creatManagerObject
    {
        //NSManagerObject或它的子类都要用NSEntityDescription来描述
        Library *libraryOne = [NSEntityDescription insertNewObjectForEntityForName:@"Library" inManagedObjectContext:_context];
        libraryOne.libraryName = @"图书馆1";
        Library *libraryTwo = [NSEntityDescription insertNewObjectForEntityForName:@"Library" inManagedObjectContext:_context];
        libraryTwo.libraryName = @"图书馆2";
         
        Book *bookOne = [NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:_context];
        bookOne.bookName = @"时间简史";
        bookOne.library = libraryOne;
        Book *bookTwo = [NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:_context];
        bookTwo.bookName = @"全球通史";
        bookTwo.library = libraryTwo;
        Book *bookThree = [NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:_context];
        bookThree.bookName = @"鲁滨逊漂流记";
        bookThree.library = libraryTwo;
         
        //利用_context同步数据至数据库
        if ([_context save:nil])
        {
            NSLog(@"添加数据成功");
        };
         
    }

        数据已经成功添加了  注意:ZBOOK中的ZLIBRARY对应的是ZLIBRARY的Z_PK,不要和代码中的1,2混淆,

     

    4.查询数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    - (void)retrieveManagerObject
    {
       //查询数据需要用到NSFetchRequest
        NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Book"];
        //用谓词进行查询找出书名中最后一个是史字的图书
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"bookName like '*史'"];
        //fetchRequest与谓词关联
        fetchRequest.predicate = predicate;
        //查询
        NSArray *resultArr = [_context executeFetchRequest:fetchRequest error:nil];
         
        //对查询到的结果进行遍历,打印书名
        if (resultArr)
        {
            for (Book *book in resultArr)
            {
                NSLog(@"bookName = %@",book.bookName);
            }
        }
         
    }

     查询结果如下       注意:这里容易造成错误的就是谓词的使用,如果没有对应得属性就会造成崩溃;

    5.修改数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    - (void)updateManagerObject
    {
       //更新数据前需要先查询到数据
        NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Book"];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"bookName = '鲁滨逊漂流记'"];
         fetchRequest.predicate = predicate;
        NSArray *resultArr = [_context executeFetchRequest:fetchRequest error:nil];
         
        if (!resultArr)
        {
            return;
        }
        //把查询到的书名全都替换成“生物医学工程”
        Book *book = [resultArr firstObject];
        book.bookName = @"生物医学工程";
        //同步数据到数据库
        if([_context save:nil])
        {
            NSLog(@"数据修改成功");
        }
        else
        {
            NSLog(@"数据修改失败");
        }
         
    }

     结果,已经把“鲁滨逊漂流记”的书名修改成了“生物医学工程”

    6.删除数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    - (void)deleteManagerObject
    {
        //删除数据前先要查询到需要删除的数据
        NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Book"];
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"bookName = '生物医学工程'"];
        fetchRequest.predicate = predicate;
        NSArray *resultArr = [_context executeFetchRequest:fetchRequest error:nil];
         
        if (!resultArr)
        {
            return;
        }
         
        Book *book = [resultArr firstObject];
        //删除数据
        [_context deleteObject:book];
        //同步至数据库
        if([_context save:nil])
        {
            NSLog(@"删除数据成功");
        }
        else
        {
            NSLog(@"删除数据失败");
        }
         
    }

       结果,“生物医学工程”这本书已经被成功删除

    7.版本迁移

     模型文件的版本迁移:

     1.原则:不能删除原来的模型文件,而是新增模文件的版本。

     2.步骤:

     (1)创建模型文件的新版本:Editor/Add Model Version

     (2)设置Current Model Version为新版本。

     (3)在配置NSPersistentStoreCoordinator时,添加设置字典,里面有相关键值对配置设置选项。

    3.实现

      (1)选中工程中的 xcdaramodeId 文件,Menu->Editor->Add Model Version

      (2)  添加完成后,xcdaramodeId 文件可以展开,可以看到新增加的Model文件 ,在右侧工具栏选择Current Model Version 为新的Model文件

       (3)在CRUD 2Z中添加新的实体和属性

         

         (4)在ViewController.m   - (void)creatSQLite方法中修代码,主要是NSPersistentStoreCoordinator的配置字典

         之前 addPersistentStoreWithType: configuration:  URL: options: error: 方法中options传的都是nil

           修改后传入配置字典

    1
    2
    3
    4
    5
    6
    7
    8
    9
    NSDictionary *optionsDic = @{
                                     //自动版本迁移
                                     NSMigratePersistentStoresAutomaticallyOption @YES,
                                     //自动映射
                                     NSInferMappingModelAutomaticallyOption @YES
                                      
                                     };
         
        [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:pathURL options:optionsDic error:nil];

         (5)运行,找到数据库进行查看Person已经被添加进来了,数据也都正确

       

        上述代码只能是对数据模型增加实体或者可选属性时,才可以这样迁移(轻量级迁移 Lightweight Migration

  • 相关阅读:
    拨号进入防盗界面
    手机开机或启动广播接收者
    time、datetime
    py 包和模块,软件开发目录规范
    递归函数
    匿名函数,内置函数
    三元表达式,列表生成式,生成器生成式
    迭代器,生成器
    XPath
    闭包,装饰器
  • 原文地址:https://www.cnblogs.com/luoxiaofu/p/5220745.html
Copyright © 2020-2023  润新知