CoreData基础用法

一、简单介绍
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的单例类。篇幅有限,这个将在下一章中介绍。

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

推荐阅读更多精彩内容