美文网首页iOS首页投稿(暂停使用,暂停投稿)iOS进阶指南
数据库----CoreData框架的创建以及涉及的谓词知识点总结

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

作者: 钎探穗 | 来源:发表于2016-06-29 22:52 被阅读259次
    • 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操作(这些方法和上面的方法相同,只不过是在创建实体描述时,里边的管理上下文的对象是自己声明属性的管理上下文对象)

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

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/kyuxjttx.html