CoreData基础用法

作者: 无处惹尘_埃 | 来源:发表于2016-11-30 16:37 被阅读76次

    一、简单介绍
    Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象。在此数据操作期间,我们不需要编写任何SQL语句。
    对象-关系映射(ORM)

    左边是关系模型,即数据库,数据库里面有张person表,person表里面有id、name、age三个字段,而且有2条记录;
    右边是对象模型,可以看到,有2个OC对象;
    利用Core Data框架,我们就可以轻松地将数据库里面的2条记录转换成2个OC对象,也可以轻松地将2个OC对象保存到数据库中,变成2条表记录,而且不用写一条SQL语句。
    二、创建模型
    上文已经介绍过,CoreData可以将一个OC对象转化成**关系模型 **(一个表格)存储在SQLite中。那么,现在我们就需要创建一个存储数据的Model类。具体操作如下:
    1.创建后缀为.xcdatamodeld的模型文件
    command+n:出现如下窗口,点击next


    弹出一个窗口,“Save as:”后面修改文件名,点击Creat,出现如下界面:


    点击“Add Entity”添加实体,出现绿色框中的“Entity”,双击“Entity”,可以更改实体的名字。比如,改为“People”。机智的骚年,你是不是想到了什么?是的,其实Entity就是一个NSObject。既然如此,我们就可以往这个叫做“Peolpe”的Entity中添加一些属性。点击Attributes下的“+”,如下图:


    有时由于项目需求,需要在Entity(例如“People”)中添加另一个Entity(例如“Car”)作为它的属性,而Car也有一个“People”属性。那么,这两个Entity是相互关联的。我们需要给它们添加关联:
    第一步:创建一个名为“Car”的Entity。既然是添加关联,我们当然要在Relationships下操作了。点击Relationships下的“+”添加需要关联的Entity( "People" )。“Relationships”:自己定义(所要添加的属性名); “Destination”:要关联的Entity("People") ; “Inverse”:这个暂时不用管它(这个时候还无法操作)。

    第二步:既然是相互关联,我们当然也要在People的Relationships下添加一个关联。与第一步类似:“Relationships”:自己定义(所要添加的属性名); “Destination”:要关联的Entity("Car") ; “Inverse”:点击会有一个选择框,我这里的选项是“ower”,选择它。


    2.创建NSManagedObject子类
    模型文件创建好后,接下来就要根据这个模型文件创建处相应的Model类,具体操作如下:点击 .xcdatamodeld文件--->Editor--->Creat NSManagedObject Subclass


    弹出一个窗口,打上勾,点击Creat,又弹出一个窗口,全钩上,Creat。最后,生成八个文件,如下图


    三、数据操作
    前文已经提过因为CoreData是苹果公司封装的数据持久化框架,所以CoreData数据持久化的操作,不需要编写SQLite语句,而是要用到一些相关的类。比如:NSManagedObjectModel、NSPersistentStoreCoordinator、NSManagedObjectContext等等。
    1.CoreData构成的类介绍
    (1)NSManagedObjectContext: 被管理者对象上下文, 相当于一个临时数据库, 我们存储或者查询都是通过这个对象来的;
    (2)NSManagedObjectModel: 被管理对象模型,可以简单的理解为可视化建模文件(.xcdatamodeld文件), 我们在可视化建模中是Entity自动生成model 方便让文件存储助理来进行管理;
    (3)NSPersistentStoreCoordinator: 文件存储助理,相当于数据库的链接器,它是CoreData的核心 负责链接所有的模块, 包括真实的存储文件;
    (4)NSManagedObject: 被管理的数据记录,相当于数据库中的表格记录;
    (5)NSFetchRequest: 获取数据的请求,相当于SQL语句;
    (6)NSEntityDescription: 实体结构,相当于表结构;
    2.CoreData核心类初始化
    CoreData核心类就是NSManagedObjectModel、NSPersistentStoreCoordinator、NSManagedObjectContext。CoreData的一系列操作都离不开这三个类,也正是因为它们这么重要,所以我们在创建工程时只要勾上CoreData选项,Xcode就会在AppDelegate.m文件中自动生成这三个类的初始化代码。

    这些代码你可以写不出来,但是一定要清楚它们的作用,下面将对这些代码做一些介绍注释:

    //获取沙盒Document目录路径
    - (NSURL*)applicationDocumentsDirectory {
    return[[[NSFileManager defaultManager]URLsForDirectory:NSDocumentDirectoryinDomains:NSUserDomainMask]lastObject];
    }
    
    //被管理的对象模型
    - (NSManagedObjectModel*)managedObjectModel {
          if(_managedObjectModel!=nil) {
          return_managedObjectModel;
          }
         //这里的@"*Model*"需要与.xcdatamodeld文件的名字一样;.xcdatamodeld编译后为.momd或.mom文件
         NSURL*modelURL = [[NSBundle mainBundle]URLForResource:@"*Model*"withExtension:@"momd"];
         _managedObjectModel= [[NSManagedObjectModel alloc]initWithContentsOfURL:modelURL];
         return_managedObjectModel;
    }
    
    //持久化存储助理:相当于数据库的连接器
    - (NSPersistentStoreCoordinator*)persistentStoreCoordinator {
           if(_persistentStoreCoordinator!=nil) {
           return_persistentStoreCoordinator;
           }
           _persistentStoreCoordinator= [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:[self managedObjectModel]];
           //CoreData是建立在SQLite之上的,数据库名称需与.cdatamodel文件同名
           NSURL*storeURL = [[self applicationDocumentsDirectory]URLByAppendingPathComponent:@"Model.sqlite"];
           NSError*error =nil;
           NSString*failureReason =@"There was an error creating or loading the application's saved data.";
           if(!     [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
            NSMutableDictionary*dict = [NSMutableDictionary dictionary];
           dict[NSLocalizedDescriptionKey] =@"Failed to initialize the application's saved data";
           dict[NSLocalizedFailureReasonErrorKey] = failureReason;
           dict[NSUnderlyingErrorKey] = error;
           error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN"code:9999userInfo:dict];
           NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
           abort();
        }
        return_persistentStoreCoordinator;
    }
    
    //被管理的上下文:操作实际内容
    - (NSManagedObjectContext*)managedObjectContext {
          if(_managedObjectContext!=nil) {
              return_managedObjectContext;
          }
          NSPersistentStoreCoordinator*coordinator = [self persistentStoreCoordinator];
          if(!coordinator) {
                 return nil;
          }
          _managedObjectContext= [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];
          [_managedObjectContext setPersistentStoreCoordinator:coordinator];
          return_managedObjectContext;
    }
    
    //保存数据
    - (void)saveContext {
    NSManagedObjectContext*managedObjectContext =self.managedObjectContext;
    if(managedObjectContext !=nil) {
    NSError*error =nil;
    if([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
    }
    }
    }
    

    3.增、删、改、查操作
    以下操作均是利用Xcode自动在AppDelegate初始化CoreData的核心对象,所以首先需要初始化一个AppDelegate对象

    AppDelegate*app=[[AppDelegate alloc]init];
    

    插入数据

    NSManagedObject*object=[NSEntityDescription insertNewObjectForEntityForName:entity inManagedObjectContext:app.managedObjectContext];
    //第一种方式
    [object setValue:@"Kevin" forKey:@"name"];
    //第二种方式
    (People*)people=object;
    object.name=@"Kevin";
    .......
    //插入操作结束后记得保存
    [app saveContext];
    

    删除数据

    [app.managedObjectContext deleteObject:object];
    [app saveContext];
    

    查询数据

         //创建取回数据请求
        NSFetchRequest*request=[[NSFetchRequest alloc]init];
        //设置检索的实体描述
        NSEntityDescription*entityDes=[NSEntityDescription entityForName:@"People" inManagedObjectContext:app.managedObjectContext];
        [request setEntity:entityDes];
        //指定对检索结果的排序方式(根据People的name属性,按升序排列)
        NSSortDescriptor*sortDestor=[[NSSortDescriptor alloc]initWithKey:@"name" ascending:YES];
        [request setSortDescriptors:@[sortDestor]];
         //创建谓词(搜索name=@"Kevin"的数据)
        NSPredicate*predicate=[NSPredicate predicateWithFormat:@"name=%@",@"Kevin"];
        request.predicate=predicate;
    
        NSError*error=nil;
        //执行请求,返回数组
        NSArray*fetchedResult=[app.managedObjectContext executeFetchRequest:request error:&error];
    

    修改数据
    修改数据其实就是将查询操作时返回的数组中的元素取出,直接修改。(数组中的元素是指向内存地址的指针)

    (People*)people=fetchedResult[0];
    people.name=@"Tom";
    

    项目开发过程中,在AppDelegate中初始化CoreData的核心对象并不是一种提倡的做法。我们通常的做法是封装一个CoreDataManager的单例类。篇幅有限,这个将在下一章中介绍。

    相关文章

      网友评论

        本文标题:CoreData基础用法

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