zoukankan      html  css  js  c++  java
  • Core Data的那点事儿~

    一、介绍下Core Data

      CoreData在早些年iOS开发中使用不多,因为其本身性能略低,以及不使用SQL语句而失去的灵活性,再加上FMDB之类封装SQLite的三方框架很好用,所以一直不受待见。最近越来越多的开发中开始使用CoreData,原因也许是因为如今的设备性能的提升,大家又慢慢的看到了CoreData的优点,比如不用SQL语句(笔者很喜欢这点,哈哈),配置使用的方式也比较简单(刚开始使用时可能感觉有点复杂,用于连接“对象”和“关系”的类好多。。但是模式本身是很简单的,也很容易实现,熟练而已)。

      下面开始好好聊聊CoreData吧,看完至少使用它不再是问题~

      Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象。在此数据操作期间,我们不需要编写任何SQL语句,这个有点类似于著名的Hibernate持久化框架,不过功能肯定是没有Hibernate强大的。

      CoreData本质是一个ORM框架 ORM Objective-Relational Mapping 这个映射就是我们的模型文件,一般ORM框架都用XML格式来映射实体Entity+属性数据库表。

      托管对象(entity) —既不是单纯的内存对象,也不是数据库中的具体的数据,它介于这两个状态之间的,我们叫他游离态的数据(很蛋疼的说法)。

      CoreData不能执行SQL语句,取而代之,操作的是对象, FMDB SQLite可以直接SQL语句,对于很多面向对象的开发者来说,操作对象更为习惯。

      给出一张图,看看“关系”和“对象”

    •  左边是关系模型,即数据库,数据库里面有张person表,person表里面有id、name、age三个字段,而且有2条记录; 右边是对象模型,可以看到,有2个OC对象; 利用Core Data框架,我们就可以轻松地将数据库里面的2条记录转换成2个OC对象,也可以轻松地将2个OC对象保存到数据库中,变成2条表记录,而且不用写一条SQL语句。

       

     

    二、coredata中的核心对象

        

    注:黑色表示类名,红色表示类里面的一个属性

    1、常规开发步骤(不理解没关系,后面有代码。。):

      (1)初始化NSManagedObjectModel对象,加载模型文件,读取app中的所有实体信息

      (2)初始化NSPersistentStoreCoordinator对象,添加持久化库(这里采取SQLite数据库)

      (3)初始化NSManagedObjectContext对象,拿到这个上下文对象操作实体,进行CRUD(创建(Create)、更新(Update)、读取(Read)和删除(Delete))操作

    2、核心对象

    (1)CoreData 持久化协调器 - NSPersistentStoreCoordinator

    NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]
    

    (2)CoreData 对象映射模型 - NSManagedObjectModel

    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    

    (3)CoreData 托管对象上下文 - NSManagedObjectContext

    1. 指定队列 _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    2. 指定协调器 [_managedObjectContext setPersistentStoreCoordinator:coordinator];

    (4)CoreDate 实体描述器 - NSEntityDescription

    (5)CoreData 托管对象 - NSManageObject

     

    三、CoreData的4个存储方式:

    1. SQLite         NSSQLiteStoreType
    2. XML            NSXMLStoreType
    3. Binary         NSBinaryStoreType
    4. 内存存储       NSInMemoryStoreType     这是个及其鸡肋的存储方式。。。。

     

    四、看代码吧~~~配置示例

    1、创建一个CoreData管理工具类,方便使用“管理上下文”

    @implementation ZQManagerCoreData
    
    //单例实现
    static ZQManagerCoreData *share;
    +(instancetype)shareManager
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
           share =  [[ZQManagerCoreData alloc]init];
        });
        return share;
    }
    
    
    //通过getter方法获取上下文:
    
    /*
        1、生成上下文需要设置持久化存储协调器!
    
        2、生成协调器又需要一个模型  
    
        3、新创建一个CoreData选项下的Data Model模型文件 
    
        4、把这个模型文件从bundle中加载到
    
    */
    -(NSManagedObjectContext *)managedContext
    {
        if (_managedContext == nil) {
    
            //模型文件的boundle 路径
            NSURL *url = [[NSBundle mainBundle] URLForResource:@"Person" withExtension:@"momd"];
            
            //需要一个模型文件
            NSManagedObjectModel *model = [[NSManagedObjectModel alloc]initWithContentsOfURL:url];
            
            //创建持久化存储协调器
            NSPersistentStoreCoordinator *per = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:model];
            
            //创建对象
            _managedContext = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];
        //数据库文件路径
    
    #warning 文件路径放在桌面是随意选的,应该放在沙盒最好
    
            NSURL *fileUrl = [NSURL fileURLWithPath:@"/Users/apple/Desktop/Person/person.db"];
            //添加数据库文件路径
            [per addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:fileUrl options:nil error:nil];
            //设置参数
            [_managedContext setPersistentStoreCoordinator:per];
            
        }
        return _managedContext;
        
    }
        
    

    2、存储数据到数据库

    //存储数据
    - (void)updata
    {
        //通过“实体描述”的类方法 insert 插入数据
    
    /*
        1、“实体描述”的类方法,需要实体,要到刚才创建的model文件中去添加实体(点击),同时注意实体的名字首字母必须大写!添加完Entity“实体”以后,设置这个实体的属性,就是对应数据库中的字段
    
        2、“实体描述”的类方法返回的是OC的对象(NSManagedObject),此对象比较特殊,是“游离”对象
    
        3、手动创建一个NSManagedObject的类文件,注意,不是普通的iOS源文件,是通过CoreData选项中的NSManagedObject ect subclass 创建的特殊类。这个类要关联刚才创建的model和model里面的实体,关联在创建的过程中点击就实现了,创建完毕后会多出四个文件(Xcode7新特性,原来是两个文件)
    
        4、导入生成文件的头文件,声明变量接收一下“实体描述”的类方法返回的值
    
        5、对这个对象进行属性操作,就是对数据库中的字段进行操作了!
    
        6、最后,使用“管理上下文”保存,就真正的写入数据库了。
    
    */
      Person *person =  [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:[ZQManagerCoreData shareManager].managedContext];
        
        
        //修改person对象的属性
        person.name = @"lisi";
        person.age = @(18);
        
        //告诉数据库存储数据
        [[ZQManagerCoreData shareManager].managedContext save:nil];
    }   
    

    3、从数据库中读取

    //取数据 fetch
    - (void)fetch
    {
            
    /*
        1、通过“管理上下文”  执行 “请求” 实现取数据
    
        2、创建一个“请求”,需要配置三个属性
    
        (1)需要一个实体描述,和保存时一样
        (2)需要一个谓词,设置检索的条件
        (3)需要一个排序,将什么属性,按照什么方式排序
    
        3、查询结果是数组,拿数组接一下,数组里面是满足条件的对象(NSManageObject,这里是子类Person)
    
    */
    
        //需要一个查询请求
        NSFetchRequest *fetchrequest = [[NSFetchRequest alloc]init];
        
        //需要一个实体描述
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:[ZQManagerCoreData shareManager].managedContext];
        fetchrequest.entity = entity;
        
        //需要一个谓词 相当于SQL语句中的where 条件判断
        NSPredicate *pre = [NSPredicate predicateWithFormat:@"age = %@",@"18"];
        fetchrequest.predicate = pre;
        
        //需要一个排序
        NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
        fetchrequest.sortDescriptors = @[sort];
        
        //执行查询请求
       NSArray *tempArray = [[ZQManagerCoreData shareManager].managedContext executeFetchRequest:fetchrequest error:nil];
        
        //打印结果
        for (Person *person in tempArray) {
            NSLog(@"person = %@",person.name);
        }
    }        
    

    另外,Xcode的友好提示:输入关键字 fetch ,系统会提示使用CoreData代码块,可以自动填充上面的取数据代码~~

  • 相关阅读:
    jq随手写图片放大
    solr查询语句示例
    solr使用语法笔记
    PHP的输出缓冲区(转)
    利用fsockopen可实现异步成功访问
    mysql自动加入添加时间列
    MySQL性能分析及explain的使用
    VS 无法启动程序
    android 编写动画
    Advanced Installer
  • 原文地址:https://www.cnblogs.com/cleven/p/5475583.html
Copyright © 2011-2022 走看看