因为Core Data比较复杂,所以我就先学习其操作用法如下:
1、新建工程,在工程根目录下新建文件或Command+n 在IOS下选择点击Core Data,在右面选择Data Model新建实体模板具体如下图:
2、在新建的实体模板内,新建实体。具体如下图:
3、可以第二种风格进行编辑显示,如下图所示。
4、为了添加数据库日志输出功能,具体如下图。
5、点击后进入以下编辑界面:
6、要使用Core Data框架,需要导入框架的头文件。为了方便使用,所以新建了一个pch文件。如下图所示:
//
// PrefixHeader.pch
// 对象关系映射ORM
//
// Created by apple on 15/9/29.
// Copyright (c) 2015年 LiuXun. All rights reserved.
//
#ifndef ______ORM_PrefixHeader_pch
#define ______ORM_PrefixHeader_pch
#import "ViewController.h"
#import "FMDatabase.h"
#import "FMDatabaseQueue.h"
#import <CoreData/CoreData.h>
#import "Person.h"
#import "Card.h"
#endif
7、在控制器的.m文件中代码实现具体步骤如下:
//
// ViewController.m
// 对象关系映射ORM
//
// Created by apple on 15/9/29.
// Copyright (c) 2015年 LiuXun. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
/*
持久化存储库的类型:
NSSQLiteStoreType SQLite数据库
NSBinaryStoreType 二进制平面文件
NSInMemoryStoreType 内存库,无法永久保存数据
虽然这3种类型的性能从速度上来说都差不多,但从数据模型中保留下来的信息却不一样。
在几乎所有的情景中,都应该采用默认设置,使用SQLite作为持久化存储库
*/
- (void)viewDidLoad {
[super viewDidLoad];
// 从应用程序包加载模型文件
NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
// 传入模型,初始化NSPersistentStoreCoordinator
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
// 构建SOLite文件路径
NSString * docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSURL * url = [NSURL fileURLWithPath:[docs stringByAppendingPathComponent:@"person.sqlite"]];
NSLog(@"路径=%@",docs);
// 添加持久化存储库,这里使用SQLite作为存储库
NSError *error = nil;
NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error];
if (store == nil) { // 直接抛出异常
[NSException raise:@"添加数据库错误" format:@"%@", [error localizedDescription]];
}
// 初始化上下文,设置persistentStoreCoordinator属性
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
context.persistentStoreCoordinator = psc;
// 传入上下文创建一个Card实体对象 NSEntityDescription:相当于一张表结构
// 下面相当于从指定上下文 指定的表结构映射出一个对象——在指定表中添加一条记录
NSManagedObject *card = [NSEntityDescription insertNewObjectForEntityForName:@"Card" inManagedObjectContext:context];
[card setValue:@"41162719930" forKey:@"no"];
// 传入上下文,创建一个Person实体对象
NSManagedObject *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];
// 设置简单属性
[person setValue:@"MJ" forKey:@"name"];
[person setValue:[NSNumber numberWithInt:27] forKey:@"age"];
// 设置Person和Card之间的关系
[person setValue:card forKey:@"card"];
// 利用上下文对象,将数据同步到持久化存储库
NSError* error1 = nil;
BOOL success = [context save:&error1];
if (!success) {
[NSException raise:@"访问数据库错误" format:@"%@", [error1 localizedDescription]];
}
/*如果想做更新操作:只要在更改了实体对象的属性后调用[context save:&error] ,就能将更改的
数据同步到数据库*/
/*初始化一个查询请求*/
/*
方法一
NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context];
方法二
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Person"];
*/
// 方法四:这种方法最简单
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
// 设置排序,按age降序排序
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:NO];
request.sortDescriptors = [NSArray arrayWithObject:sort];
// 设置条件过滤
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@",@"*J"];
request.predicate = predicate;
// 执行请求
NSError *error3 = nil;
NSArray *objs = [context executeFetchRequest:request error:&error3];
if (error3) {
[NSException raise:@"查询错误" format:@"%@",[error3 description]];
}
/*遍历数据*/
for(NSManagedObject *obj in objs)
{
NSLog(@"name=%@",[obj valueForKey:@"name"]);
}
// 删除数据——传入需要删除的实体对象
// [context deleteObject:person];
// // 将结果同步到数据库
// NSError * error4 = nil;
// [context save:&error4];
// if (error4) {
// [NSException raise:@"删除错误" format:@"%@", [error4 localizedDescription]];
// }
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
8、点击运行或command+R 输出日志如下所示:
9、打开输出的沙盒路径,发现生成的数据库文件如下:
10 、打开数据库文件.sqlite如下:
11、因为在别的地方会经常使用模板类,所以可以将存在的实体模板转化为对应的实体类。
具体步骤如下:
<1> 新建文件,或command+R 选择Core Data——>NSmanagedObject subClass 如下如图所示:
<2> 点击下一步,选择所要生成实体类的实体所在的模板。
<3> 选择想要生成类的实体
<4>点击下一步,生成对应的实体类Card和Person如下:
Card.h
//
// Card.h
// 对象关系映射ORM
//
// Created by apple on 15/9/30.
// Copyright (c) 2015年 LiuXun. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class Person;
@interface Card : NSManagedObject
@property (nonatomic, retain) NSString * no;
@property (nonatomic, retain) Person *person;
@end
card.m
//
// Card.m
// 对象关系映射ORM
//
// Created by apple on 15/9/30.
// Copyright (c) 2015年 LiuXun. All rights reserved.
//
#import "Card.h"
#import "Person.h"
@implementation Card
@dynamic no;
@dynamic person;
@end
Person.h
//
// Person.h
// 对象关系映射ORM
//
// Created by apple on 15/9/30.
// Copyright (c) 2015年 LiuXun. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class NSManagedObject;
@interface Person : NSManagedObject
@property (nonatomic, retain) NSNumber * age;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSManagedObject *card;
@end
Person.m
//
// Person.m
// 对象关系映射ORM
//
// Created by apple on 15/9/30.
// Copyright (c) 2015年 LiuXun. All rights reserved.
//
#import "Person.h"
#import <CoreData/NSManagedObject.h>
@implementation Person
@dynamic age;
@dynamic name;
@dynamic card;
@end
运行发现没有错误,把实体类的头文件导入到pch文件中。整个工程就可直接使用实体模型类。
<5>当工程建成后,有时为了扩展为已经存在的实体类添加子类方法步骤如下:
5.1 同样点开已经存在的实体模板,添加实体如下:
5.2 为其添加日期类型的变量
5.3 为其添加字符串类型变量
5.4 为实体添加继承
5.5 然后为新的实体生成实体类,步骤上同。如下所示
5.6 运行发现程序崩溃。可能是因为编译运行过的原因,打开沙盒删除已经存在的数据库。再次编译运行错误消失,说明每次更改实体模板后,都要删除已经存在的数据库文件。再次编译运行即可。结果如下: