http://www.cnblogs.com/xiaodao/archive/2012/10/08/2715477.html

一、概念

1.Core Data 是数据持久化存储的最佳方式

2.数据最终的存储类型可以是:SQLite数据库,XML,二进制,内存里,或自定义数据类型

在Mac OS X 10.5Leopard及以后的版本中,开发者也可以通过继承NSPersistentStore类以创建自定义的存储格式

3.好处:能够合理管理内存,避免使用sql的麻烦,高效

4.构成:

(1)NSManagedObjectContext(被管理的数据上下文)

操作实际内容(操作持久层)

作用:插入数据,查询数据,删除数据

(2)NSManagedObjectModel(被管理的数据模型)

数据库所有表格或数据结构,包含各实体的定义信息

作用:添加实体的属性,建立属性之间的关系

操作方法:视图编辑器,或代码

(3)NSPersistentStoreCoordinator(持久化存储助理)

相当于数据库的连接器

作用:设置数据存储的名字,位置,存储方式,和存储时机

(4)NSManagedObject(被管理的数据记录)

相当于数据库中的表格记录

(5)NSFetchRequest(获取数据的请求)

相当于查询语句

(6)NSEntityDescription(实体结构)

相当于表格结构

(7)后缀为.xcdatamodeld的包

里面是.xcdatamodel文件,用数据模型编辑器编辑

编译后为.momd或.mom文件

5.依赖关系

二、基于SQLite数据库时,Core Data的简单使用

和SQLite的区别:只能取出整个实体记录,然后分解,之后才能得到实体的某个属性

1.构建流程

包括:创建数据上下文,创建数据模型,创建数据持久化存储助理

(1)若是新建的工程,选择空白应用程序,next

勾选Use Core Data选项

此时生成的工程文件AppDelegate中,会自动生成被管理的数据上下文等相关代码

(2)比如AppDelegate.h文件中,自动生成

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; - (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;

方法saveContext表示:保存数据到持久层(数据库)

方法applicationDocumentsDirectory表示:应用程序沙箱下的Documents目录路径

(例如/var/mobile/Applications/5FG80A45-DFB5-4087-A1B1-41342A977E21/Documents/)

(3)比如AppDelegate.h文件中,自动生成

@synthesize managedObjectContext = __managedObjectContext;
@synthesize managedObjectModel = __managedObjectModel;
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;

保存数据到持久层

- (void)applicationWillTerminate:(UIApplication *)application
{
[self saveContext];
}
- (void)saveContext
{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}

Documents目录路径

- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

被管理的数据上下文

初始化的后,必须设置持久化存储助理

- (NSManagedObjectContext *)managedObjectContext
{
if (__managedObjectContext != nil) {
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
__managedObjectContext = [[NSManagedObjectContext alloc] init];
[__managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return __managedObjectContext;
}

被管理的数据模型

初始化必须依赖.momd文件路径,而.momd文件由.xcdatamodeld文件编译而来

- (NSManagedObjectModel *)managedObjectModel
{
if (__managedObjectModel != nil) {
return __managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"TestApp" withExtension:@"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return __managedObjectModel;
}

持久化存储助理

初始化必须依赖NSManagedObjectModel,之后要指定持久化存储的数据类型,默认的是NSSQLiteStoreType,即SQLite数据库;并指定存储路径为Documents目录下,以及数据库名称

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (__persistentStoreCoordinator != nil) {
return __persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"TestApp.sqlite"];
NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return __persistentStoreCoordinator;
}

如果不是新工程,也可以自己写入相关代码

(4)此外还生成了TestApp.xcdatamodeld文件

(5)还自动链接了CoreData.framework

(6)在预编译头.pch文件中,加入导入了CoreData.h头文件

#import <CoreData/CoreData.h>

2.创建数据模型(数据模型编辑器操作)

(1)创建实体

选中.xcodedatamodel对象

在右边的数据模型编辑器的底部工具栏点击Add Entity添加实体

在最右侧栏对实体命名

(2)创建实体属性

选中实体,点击底部工具栏的Add Attribute添加属性

选中新添加的属性,对属性进行命名,并设置属性的数据类型Attribute Type

(3)为两个实体建立关系

选中一个实体,在底部工具栏点击Add Relationship添加关系

选中新关系,对关系添加名称,目标destination设置为另个实体

(4)建立返回关系

(当你建立一个目标关系,最好建立一个返回关系)

在另一个实体中建立一个关系并命名,设置目标对象为这之前的实体

并在Inverse属性选这之前的关系名称

(5)设置两个关系的删除规则Delete Rule,都为关联模式

关联模式cascade:其中一个数据被删除,另一个实体中的数据也会跟着删除

(6)最终两个对象的关系图为

切换Editor Stype按钮

会看到另一种编辑方式:

3.插入数据

在AppDelegate.m的application:didFinishLaunchingWithOptions:方法里,调用自定义方法

insertCoreData插入数据,代码如下:

- (void)insertCoreData
{
NSManagedObjectContext *context = [self managedObjectContext]; NSManagedObject *contactInfo = [NSEntityDescription insertNewObjectForEntityForName:@"ContactInfo" inManagedObjectContext:context];
[contactInfo setValue:@"name B" forKey:@"name"];
[contactInfo setValue:@"birthday B" forKey:@"birthday"];
[contactInfo setValue:@"age B" forKey:@"age"]; NSManagedObject *contactDetailInfo = [NSEntityDescription insertNewObjectForEntityForName:@"ContactDetailInfo" inManagedObjectContext:context];
[contactDetailInfo setValue:@"address B" forKey:@"address"];
[contactDetailInfo setValue:@"name B" forKey:@"name"];
[contactDetailInfo setValue:@"telephone B" forKey:@"telephone"]; [contactDetailInfo setValue:contactInfo forKey:@"info"];
[contactInfo setValue:contactDetailInfo forKey:@"details"]; NSError *error;
if(![context save:&error])
{
NSLog(@"不能保存:%@",[error localizedDescription]);
}
}

创建数据上下文,调用insertNewObjectForName方法,创建两个数据记录NSManagedObject,然后就可以对之前数据模型编辑视图中定义的属性进行赋值。此时的数据只在内存中被修改,最后调用数据上下文的save方法,保存到持久层

4.查询数据

在调用了insertCoreData之后,可以调用自定的查询方法dataFetchRequest来查询插入的数据

- (void)dataFetchRequest
{
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ContactInfo" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *info in fetchedObjects) {
NSLog(@"name:%@", [info valueForKey:@"name"]);
NSLog(@"age:%@", [info valueForKey:@"age"]);
NSLog(@"birthday:%@", [info valueForKey:@"birthday"]);
NSManagedObject *details = [info valueForKey:@"details"];
NSLog(@"address:%@", [details valueForKey:@"address"]);
NSLog(@"telephone:%@", [details valueForKey:@"telephone"]);
}
}

fetchRequest相当于sql查询语句的包装类,需要用setEntity方法,来指定具体查询的实体结构(表结构)

通过NSEntityDescription的entityForName方法来,返回指向该具体实体结构的指针

然后调用executeFetchRequest:error:方法,来执行查询操作,如果操作成功,则返回对应的数据记录数组

其中,可以通过NSManagedObject数据记录对象里关联的属性,查询另一个数据记录对象里的属性

5.数据模版

为每个实体生成一个NSManagedObject子类

上面设置数据和获取数据时,使用的是Key-Value方式,更好的方法是通过生成强类型的NSManagedObject的子类,通过类的成员属性来访问和获取数据

(1)在数据编辑器视图中选中实体对象,

选则file菜单,点击new,点击file...,选择Core Data项,选择NSManagedObject subclass,生成该实体同名的类,

继承于NSManagedObject

生成对应的ContactInfo.h文件

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h> @class ContactDetailInfo; @interface ContactInfo : NSManagedObject @property (nonatomic, retain) NSString * age;
@property (nonatomic, retain) NSString * birthday;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) ContactDetailInfo *details; @end

和ContactInfo.m文件

其中,@dynamic告诉编译器不做处理,使编译通过,其getter和setter方法会在运行时动态创建,由Core Data框架为此类属性生成存取方法

#import "ContactInfo.h"
#import "ContactDetailInfo.h" @implementation ContactInfo @dynamic age;
@dynamic birthday;
@dynamic name;
@dynamic details; @end

以及ContactDetailInfo.h文件

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h> @class ContactInfo; @interface ContactDetailInfo : NSManagedObject @property (nonatomic, retain) NSString * address;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * telephone;
@property (nonatomic, retain) ContactInfo *info; @end

和ContactDetailInfo.m文件

#import "ContactDetailInfo.h"
#import "ContactInfo.h" @implementation ContactDetailInfo @dynamic address;
@dynamic name;
@dynamic telephone;
@dynamic info; @end

此时,数据模型编辑器视图最右边栏中,实体的class就变成具体的类名

之前用Key-Value的代码就可以修改为:

#import "ContactInfo.h"
#import "ContactDetailInfo.h"
- (void)insertCoreData
{
NSManagedObjectContext *context = [self managedObjectContext]; ContactInfo *contactInfo = [NSEntityDescription insertNewObjectForEntityForName:@"ContactInfo" inManagedObjectContext:context];
contactInfo.name = @"name B";
contactInfo.birthday = @"birthday B";
contactInfo.age = @"age B"; ContactDetailInfo *contactDetailInfo = [NSEntityDescription insertNewObjectForEntityForName:@"ContactDetailInfo" inManagedObjectContext:context];
contactDetailInfo.address = @"address B";
contactDetailInfo.name = @"name B";
contactDetailInfo.telephone = @"telephone B"; contactDetailInfo.info = contactInfo;
contactInfo.details = contactDetailInfo; NSError *error;
if(![context save:&error])
{
NSLog(@"不能保存:%@",[error localizedDescription]);
}
}
- (void)dataFetchRequest
{
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ContactInfo" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (ContactInfo *info in fetchedObjects) { NSLog(@"name:%@", info.name);
NSLog(@"age:%@", info.age);
NSLog(@"birthday:%@", info.birthday);
ContactDetailInfo *details = info.details;
NSLog(@"address:%@", details.address);
NSLog(@"telephone:%@", details.telephone);
}
}

三、数据库相关

1.打印隐藏的sql语句:

在Edit Scheme中选择Run,之后进入Arguments标签,添加参数:“-com.apple.CoreData.SQLDebug 1”

2.使用SQLite存储时,数据库结构

存储的SQLite数据库表名称:大写“Z”加上实体名称大写,一个实体相当于一张表

具体的字段名称:大写“Z”加上实体属性名称大写

  1. 先按照网上的教程,建一个简单的带coredata的项目
  2. 再 添加一个 UserInfo 对象(表)(按照网上的教材,可视化方式添加)
  3. 然后在AppDelegate.m中按如下修改,(只添加了4个方法)
  4. 然后运行,看控制台日志
  5. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  6. {
  7. self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  8. // Override point for customization after application launch.
  9. self.window.backgroundColor = [UIColor whiteColor];
  10. [self.window makeKeyAndVisible];
  11. [self addUser];
  12. [self gainDatas];
  13. return YES;
  14. }
  15. //添加
  16. -(void)addUser{
  17. UserInfo * userInfo  = [NSEntityDescription insertNewObjectForEntityForName:@"UserInfo"
  18. inManagedObjectContext:self.managedObjectContext];
  19. userInfo.name = @"dage";
  20. userInfo.password = @"password3";
  21. NSError *error = nil;
  22. if (![self.managedObjectContext save:&error]) {
  23. NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
  24. abort();
  25. }
  26. NSLog(@"add success");
  27. }
  28. //查询
  29. -(void)gainDatas {
  30. NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
  31. [fetchRequest setEntity:[NSEntityDescription entityForName:@"UserInfo" inManagedObjectContext:self.managedObjectContext]];
  32. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like[cd]'baobao'"];//查询条件
  33. // NSPredicate *predicate = [NSPredicate predicateWithFormat:@"password='password3'"];//查询条件
  34. NSMutableArray *sortDescriptors = [NSMutableArray array];    //排序用
  35. [sortDescriptors addObject:[[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES] ];  //排序用
  36. [fetchRequest setPredicate:predicate];  //查询条件
  37. [fetchRequest setFetchBatchSize:5];     //分页
  38. [fetchRequest setSortDescriptors:sortDescriptors];  //排序
  39. [fetchRequest setReturnsObjectsAsFaults:NO];
  40. [fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:@"name", @"password", nil]];  //查询的字段,一般不需要
  41. NSError *error = nil;
  42. NSArray *fetchedItems = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
  43. if (fetchedItems == nil) {
  44. NSLog(@"fetch request resulted in an error %@, %@", error, [error userInfo]);
  45. }else {
  46. NSLog(@"fetchedItems=%d",fetchedItems.count);
  47. for (UserInfo *user in fetchedItems) {
  48. NSLog(@"user.authour=%@",user.name);
  49. // [self deleteUser:user];  //删除
  50. // [self updateUser:user];  //更新
  51. }
  52. }
  53. }
  54. //删除:NSManagedObject对象必须先取出来,用managedObjectContext删除,保存就好
  55. -(void)deleteUser:(id)user{
  56. [self.managedObjectContext deleteObject:user];
  57. NSError *error = nil;
  58. if (![self.managedObjectContext save:&error]) {
  59. NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
  60. abort();
  61. }
  62. NSLog(@"delete success");
  63. }
  64. //更新:直接修改对象,保存managedObjectContext就好
  65. -(void)updateUser:(UserInfo*)user{
  66. user.name = @"baobao";   //修改后,直接保存managedObjectContext就可以了
  67. NSError *error = nil;
  68. if (![self.managedObjectContext save:&error]) {
  69. NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
  70. abort();
  71. }
  72. NSLog(@"update success");
  73. }

iphone数据存储之-- Core Data的使用(一)的更多相关文章

  1. iOS开发之数据存储之Core Data

    1.概述 Core Data框架提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite3数据库文件中,也能够将保存在数据库中的数据还原成OC对象.在此数据操作期间,不需要 ...

  2. IOS 数据存储之 Core Data详解

    Core Date是ios3.0后引入的数据持久化解决方案,它是是苹果官方推荐使用的,不需要借助第三方框架.Core Date实际上是对SQLite的封装,提供了更高级的持久化方式.在对数据库操作时, ...

  3. IOS 数据存储之 Core Data具体解释

    Core Date是ios3.0后引入的数据持久化解决方式,它是是苹果官方推荐使用的.不须要借助第三方框架.Core Date实际上是对SQLite的封装.提供了更高级的持久化方式.在对数据库操作时, ...

  4. (转)iphone数据存储之-- Core Data的使用

    原文:http://www.cnblogs.com/xiaodao/archive/2012/10/08/2715477.html iphone数据存储之-- Core Data的使用(一)   一. ...

  5. iphone数据存储之-- Core Data的使用

    一.概念 1.Core Data 是数据持久化存储的最佳方式 2.数据最终的存储类型可以是:SQLite数据库,XML,二进制,内存里,或自定义数据类型 在Mac OS X 10.5Leopard及以 ...

  6. iOS教程:如何使用Core Data – 预加载和引入数据

    这是接着上一次<iOS教程:Core Data数据持久性存储基础教程>的后续教程,程序也会使用上一次制作完成的. 再上一个教程中,我们只做了一个数据模型,之后我们使用这个数据模型中的数据创 ...

  7. iOS:Core Data 中的简单ORM

    我们首先在xcdatamodel文件中设计我们的数据库:例如我建立一个Data的实体,里面有一个String类型的属性name以及一个Integer类型的num: 然后选中Data,添加文件,选择NS ...

  8. iOS开发中的4种数据持久化方式【二、数据库 SQLite3、Core Data 的运用】

                   在上文,我们介绍了ios开发中的其中2种数据持久化方式:属性列表.归档解档.本节将继续介绍另外2种iOS持久化数据的方法:数据库 SQLite3.Core Data 的运 ...

  9. 四种数据持久化方式(下) :SQLite3 和 Core Data

    在上文,我们介绍了iOS开发中的其中2种数据持久化方式:属性列表.归档解档. 本节将继续介绍另外2种iOS持久化数据的方法:数据库 SQLite3.Core Data 的运用: 在本节,将通过对4个文 ...

随机推荐

  1. PDA设备小知识--(IP)工业防护等级含义

    IP(INTERNATIONAL PROTECTION)防护等级是专门的工业防护等级,,它将电器依其防尘.防湿气之特性加以分级.IP防护等级是由两个数字所组成,第1个数字表示电器离尘.防止外物侵入的等 ...

  2. maven integration with eclipse 3.0.4 does not work with NTLM proxy

    Recently downloaded m2e(maven integration with eclipse). The version is 3.0.4. My environment is beh ...

  3. IDL简介与corba入门案例

    IDL接口定义语言简介   IDL用中立语言的方式进行描述,能使软件组建(不同语言编写的)间相互通信. IDL提供了一个桥来连接不同的系统. Corba 上的服务用IDL描述,将被映射为某种程序设计语 ...

  4. [poj3274]排排站(Hash)

    题目:http://poj.org/problem?id=3274 题目大意:http://www.wikioi.com/problem/1247/ (此题中文版) 分析: 令sum[i][j]表示a ...

  5. beta版本贡献率

    队名:攻城小分队 031302410 郭怡锋 : 占比:50% 031302411 洪大钊: 占比:30% 031302206 陈振贵: 占比:10% 031302416 黄伟祥: 占比:10%

  6. struts2支持的结果类型

    在struts2-core.jar/struts-default.xml中,我们可以找到关于result-type的一些配置信息,从中可以看出struts2组件默认为我们提供了这 些result-ty ...

  7. C/C++语言算法题——替换

    [问题] Description 给定一个有限长度的非负整数序列.一次操作是指从第一个元素开始,依次把数列中的每个数替换为它右边比它小的数的个数.对该数列不断进行这个操作.总有一个时刻该数列将不再发生 ...

  8. [转]Java静态方法为什么不能访问非静态方法

    非静态方法(不带static)可以访问静态方法(带static),但是反过来就不行,为什么呢? ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 publi ...

  9. iOS开发小技巧--UIScrollView内部子控件添加约束的注意点

    注意:用UIScrollView时布局子控件的时候,不要相对于UIScrollView来添加约束,这样做不是设置子控件的位置,反而是设置了UIScrollView的contentSize 子控件的尺寸 ...

  10. JSP九个内置对象

    JSP内置对象有: 1.request对象      客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应.它是HttpServletRequest类的实例. 2.r ...