数据库----CoreData框架的创建以及涉及的谓词知识点总结

  • CoreData概念.

是一种提供对象关系映射的功能,将OC对象转换成数据,保存在SQLite数据库文件中数据持久化框架,用来解决对象生命周期管理,对象关系图管理,和持久化等方面相关问题的,负责在数据库中存储数据,底层也是类似于SQLite的技术实现.

  • CoreData优点:

    1:可视化,不用再写SQL语句,大量简化代码,有undo/redo能力
    2:可以实现多种文件格式:NSSQLiteStoreType,NSXMLStoreType
    3:与iOS紧密结合,只能用于开发iOS,开发效率会高一点
    4:存储内容,以对象形式存储,数据存储结构简单,符合面向对象的思想(持久化:把数据保存到一个文件,而不是内存)

  • CoreData缺点:

CoreData的代码运行效率没直接使用sql代码的运行效率高


  • 而之前说过的SQLite
  1. 是一个轻量级数据库,且功能强大的关系型数据库,很容易被嵌入到应用当中,可移植性高,可在多个平台使用
  1. 和CoreData框架不一样的是,sqlite是使用程序式的,sqlite的主要操作方法是直接操作数据表
  2. 基于C接口,使用sql语句,代码繁琐
  3. 在处理大量数据时,表关系更直观一些
  4. OC中不是可视化的

下边说一下CoreData的核心对象:

1:. ** NSManagedObjectContext:**(被管理了上下文),操作实际内容(对持久层的一个操作),插入数据,查询数据,删除数据,修改数据,是我们开发中主要交互的类,数据的CRUD都通过这个Context(上下文)去触发命令并返回结果.

2:. NSManagedObjectModel:(被管理的数据模型),包含了各个实体(相当于SQL中的表)的定义信息,包含了实体(表)或者是数据库的结构.添加实体属性(字段),建立属性之间的关系.

  • 操作方法:视图编辑器,也可用代码.
    (构建数据库的表结构,表字段类型,表与表之间的关系等,凡是和数据结构有关系的定义,通通都通过这个类来管理)

3:. NSPersistentStoreCoordinator:(持久化存储助理)相当于数据库的连接器

  • 作用:设置数据存储的名字,位置,存储方法,存储时机.
  • 原理:从下层文件取出数据,交给上层的被管理对象上下文.实际上,这个类才是真正意义上跟数据库打交道的(.sqlite文件),主要根据NSManagedObjectModel执行表结构的建立,通过 NSManagedObjectContext的命令执行数据交互.

下边我还是通过一些简单的例子给以说明下.(这里我用的是多表关联)
说之前先插一句:多表关联
CoreData在存储复杂数据关系时,一张表难以满足需求,此时就需要了解使用CoreData的多表关联
eg:学科表和课程表的关系:一门学科里有多个课程(一对多);而单一课程只能对应一门学科(一对一)
表之间就是靠这种相互约束的关系建立关联.

DDE60E01-34FD-4993-8E6E-E14CC405166E.png

首先就是在建工程时勾选UseCoreData按钮.
其次就是在工程中生成的CoreData______.xcdatamodeld文件里对实体进行创建关联

0FD45A37-A815-436E-9932-D94659D26C85.png

把创建好的实体生成模型

A1508986-DB3A-42F5-909B-67BAE0468B61.png

通过上图操作可以生成对应的文件.注意文件中的属性类型一定要是关联好的实体名,否则删了重建
下边的代码分别实现了数据的CRUD

- (void)add{
    //创建实体描述
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Subject" inManagedObjectContext:self.managedObjectContext];
    //创建subject实体对象,然后告诉上下文,让它做好添加准备,然后将subject实体对象添加到数据库中
    //创建subject实体
    Subject *sub = [[Subject alloc]initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext];
    //给对象赋值
    sub.subjectName = @"iOS";
    //将课程对象通过实体描述类创建出来
    Course *course = [NSEntityDescription insertNewObjectForEntityForName:@"Course" inManagedObjectContext:self.managedObjectContext];
    course.courseName = @"oc语言";
    Course *course1 = [NSEntityDescription insertNewObjectForEntityForName:@"Course" inManagedObjectContext:self.managedObjectContext];
    course1.courseName = @"c语言";
    //将这两门课程放入集合当中存储,赋值
    NSSet *set = [NSSet setWithObjects:course,course1, nil];
    //给集合赋值
    sub.subject = set;
    BOOL result = [self.managedObjectContext save:nil];
    if (result) {
        NSLog(@"插入数据成功");
    }else{
        NSLog(@"插入数据失败");
    }
}
#pragma mark---删-----
- (void)delete{
    
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Subject"];
    //找到删除的条件
    request.predicate = [NSPredicate predicateWithFormat:@"subjectName = %@",@"H5"];
    //由context根据删除条件执行相关操作
    NSArray *array = [self.managedObjectContext executeFetchRequest:request error:nil];
    //遍历结果
    for (Subject *sub in array) {
        [self.managedObjectContext deleteObject:sub];
    }
    if ([self.managedObjectContext save:nil]) {
        NSLog(@"删除成功");
    }else{
    
        NSLog(@"删除失败");
    }
}

#pragma mark---改-----
- (void)update{
    //实例化一个查询请求
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Subject"];
    //设置查询条件
    request.predicate = [NSPredicate predicateWithFormat:@"subjectName CONTAINS 'OS'"];//包含内容加单引号
    //由context按照查询条件进行相关操作
    NSArray *array = [self.managedObjectContext executeFetchRequest:request error:nil];
    //遍历结果,更新信息
    for (Subject *sub in array) {
        //更新信息
        sub.subjectName = @"H5";
    }
    //保存
    if ([self.managedObjectContext save:nil]) {
        NSLog(@"更新成功");
    }else{
        NSLog(@"更新失败");
    }
}
#pragma mark---查-----
- (void)select{
    //实例化一个查询请求
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Subject"];
    //设置查询条件
    request.predicate = [NSPredicate predicateWithFormat:@"subjectName = 'H5'"];//包含内容加单引号
 //读取数据库的游标偏移量,从游标开始读取数据
//    request.fetchOffset = 17;
    //每次要取多少数据,
//    request.fetchLimit = 3;
    //从数据库里每次加载2条数据来筛选数据
//    request.fetchBatchSize =  2;

    //由context按照查询条件进行相关操作
    NSArray *array = [self.managedObjectContext executeFetchRequest:request error:nil];
    //遍历结果
    for (Subject *sub in array) {
        NSLog(@"name:%@",sub.subjectName);
    }
    //保存
    if ([self.managedObjectContext save:nil]) {
        NSLog(@"查询成功");
    }else{
        NSLog(@"查询失败");
    }
    
}

代码中用到了谓词,可用谓词进行模糊查询

1.BEGINSWITH:检查某个字符串是否以指定的字符串开头(如判断字符串是否以a开头:BEGINSWITH 'a'

2.ENDSWITH:检查某个字符串是否以指定的字符串结尾

3.CONTAINS:检查某个字符串是否包含指定的字符串

4.LIKE:检查某个字符串是否匹配指定的字符串模板。其之后可以跟?代表一个字符和*代表任意多个字符两个通配符。比如"name LIKE '*ac*'",这表示name的值中包含ac则返回YES;"name LIKE '?ac*'",表示name的第2、3个字符为ac时返回YES。

5.MATCHES:检查某个字符串是否匹配指定的正则表达式。虽然正则表达式的执行效率是最低的,但其功能是最强大的,也是我们最常用的。

6.使用谓词过滤不可变集合和可变集合的区别是:过滤不可变集合时,会返回符合条件的集合元素组成的新集合;过滤可变集合时,没有返回值,会直接剔除不符合条件的集合元素

关于谓词的更多详细整理可参考:


说了这么多,那么对于一开始创建工程时,没有勾选Use Core Data选项的工程,想要中途创建CoreData文件,要怎么办呢?

  • 创建CoreData框架的步骤:
  • 1,创建模型文件
创建模型文件.png

2,添加实体(这步和上面介绍的操作一样)
3,创建实体类

创建实体类.png

4,生成上下文,关联模型文件生成数据库

我是先声明一个管理上下文的属性,方便进行CURD的操作使用
@property (nonatomic, strong) NSManagedObjectContext *managedObject;

#pragma mark----使用NSManagedObjectContext方法,如果bundles为nil会把bundles里面的所有模型文件的表放在一个数据库)
//创建context
- (void)creatContext{
//创建上下文
    _managedObject = [[NSManagedObjectContext alloc]initWithConcurrencyType:(NSMainQueueConcurrencyType)];
    //实例化model
    NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
    //数据存储调度器(持久化助理)
    //store添加路径
    NSString *doccumentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject ];
//    NSLog(@"%@",doccumentPath);
    NSString *coredatapath = [doccumentPath stringByAppendingPathComponent:@"movie.sqlite"];
    NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:model];
    self.managedObject.persistentStoreCoordinator = store;
    [store addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:coredatapath] options:nil error:nil];
}

  • 5,保存对象到数据库
  • 6,从数据库获取对象
  • 7更新,进行CURD操作(这些方法和上面的方法相同,只不过是在创建实体描述时,里边的管理上下文的对象是自己声明属性的管理上下文对象)

注意:我们在使用时一个数据库一个模型文件,两个数据库两个模型文件,一个数据库对应一个上下文,这样可避免数据量大时,多表关联时,出现混乱.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容