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

时间: 2024-08-03 15:29:56

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

ios CoreData框架的使用,对上下文数据的增删改查,表与表之间的关联,1对多,1对1,谓词查询,多表连接

这里是只是代码,因为博客插入图片效果不是很好,我自己写的总结比较详细,有兴趣的朋友可以在评论里留下邮箱,我收到后会发给大家. 转载注明出处,重视原创者的劳动成果,谢谢! - (void)viewDidLoad { [super viewDidLoad]; [self _creatTable];//插入数据 //    [self _query];// 查询数据 // KVC很霸道,即使readonly通过kvc也可赋值,kvo精华 //    Book * book = [[Book alloc

Mybatis学习总结(二)—使用接口实现数据的增删改查

在这一篇中,让我们使用接口来实现一个用户数据的增删改查. 完成后的项目结构如下图所示: 在这里,person代表了一个用户的实体类.在该类中,描述了相关的信息,包括id.name.age.id_num信息.而personMapper则是该实体类的一个配置文件.需要注意的是,在上一篇博文中,namespace属性的值是其本身,而在这一篇中,使用的是接口.那么两者有什么区别呢?使用接口,那么相关的操作方法不用自己去实现,只需要调用该接口的相关的方法就能够实现相应的功能. 那么,在这里就有一个问题,接

yii中数据的"增删改查"相关工作!(此文比较乱,需细看)

使用findByPk()根据数据表主键查询的是对象,不需要使用foreach()循环出来 但是使用findall()和find()查询的是对象类型的数组需要使用foreach()循环出来 ======================================= public function getMinLimit () { $sql = "..."; $result = yii::app()->db->createCommand($sql); $query = $r

最简单的jsp+servlet的增删改查代码

package ceet.ac.cn.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import ceet.ac.cn.model.Admin; public class AdminDao {

四种简单的sql语句(增删改查语句)

四种简单的sql语句(增删改查语句) 一.插入语句 insert into [table] ([column],[column],[column]) values(?,?,?) 二.删除语句 delete from [table] where column = ? 三.修改语句 update [table] set column = ? where column = ? 四.查询语句 1)查询单条记录的所有字段 select * from [table] where [column] = ? 2

Node.js + MySQL 实现数据的增删改查

通过完成一个 todo 应用展示 Node.js + MySQL 增删改查的功能.这里后台使用 Koa 及其相应的一些中间件作为 server 提供服务. 初始化项目 $ mkdir node-crud && cd $_ $ yarn init -y && npx gitignore node 上面的命令创建了一个空文件夹 node-crud,进入之后初始化一个 package.json 以及创建 .gitignore 文件. 安装 Koa 并创建 app.js 以启动一个

数据的增删改查(三层)

进行数据操作必然少了对数据的增删改查,用代码生成器生成的代码不是那么满意!方便在今后使用,这里就主要写“数据访问层(Dal)” 注:这里由于是用于用于测试时,临时建的数据库用于测试使用,在实际使用过程中些许改点参数就可以使用了 /// <summary> /// 是否存在该记录 /// </summary> public bool Exists(long Id) { string sql = "select count(*) Name from t_temp where

Mysql学习笔记(三)对表数据的增删改查。

写在前面:(一些牢骚,可以直接跳到分割线后) 太过敏感的人不会快乐,不幸的是我正是这种性格的人. 从培训机构毕业后,迫于经济方面的压力,和当时的班里的一个同学住在了一起,我们在一个公司上班.谁知道这都是不开心生活的源头,从每天早晨开始心情就很糟糕.他是个脾气很慢的人,我是个急脾气,特别是在早上上班的时候.由此种种吧,实在是不胜枚举.算了,还是不说了,太痛苦了,我不太喜欢说别人的坏话.我是学心理学的,已经用各种方法去安慰自己,但是都不太奏效. 回想以往和朋友的交往中,我虽然不算十分合群的人,但绝对

Mysql入门-对表数据的增删改查

这一部分是最简单的,也是最麻烦的.简单是因为其实只包括增删该插四个部分.大体上看,增加数据.删除数据.修改数据.查询数据都不麻烦啊,我们日常都是常用的.这个谁不会呢?以前在培训机构学mysql的时候,我就知道,程序员的成长路程上的一个瓶颈就在于数据库.如何书写高维护性的sql语句,如何能保持高维护性的同时又保持执行的高效率,这是个难题.我最近在做一个比较棘手的项目,常常left join 5~6张表,扫表10几万,查询速度慢的惊人.10几万还仅仅是测试数据,等真正的项目上线,数据量可能会达到百万