您的位置:首页 > 移动开发 > IOS开发

IOS_数据存储之CoreData

2014-05-31 23:48 375 查看
H:/1125/01_CoreData_ViewController.h
//  ViewController.h
//  CoreData演练
//  Created by apple on 13-11-25.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end

H:/1125/01_CoreData_ViewController.m
//  ViewController.m
//  CoreData演练
//  Created by apple on 13-11-25.
//  Core Data调试edit scheme(-com.apple.CoreData.SQLDebug)
#import "ViewController.h"
#import <CoreData/CoreData.h>
#import "Person.h"
#import "Book.h"
/*	CoreData使用步骤:
1,工程中,新建File,选择左侧Core Data
右边选择,Data Model,点击create
2,此时工程中出现,model.xcdatamodeld文件
点击中间下面的 add entity
3,中间的entities下面出现一个文件将其改名为person
4,工程右侧 attributes 点击加号+
为person这个entity添加属性name 类型为string
5,选中model.xcdatamodeld右击,	新建一个new file
6,选择左侧Core Data
右边选择,NSManagedObject subclass,点击create
一路next,最后,自动生成person.h 和person.m
------------------------------------------------
2,又回到前面,点击model.xcdatamodeld文件
点击中间的下面的 add entity,添加一个实体,
3,中间的entities下面出现一个文件将其改名为book
4,工程右侧 attributes 点击加号+
为book这个entity添加属性name 类型为string
5,选中model.xcdatamodeld右击,	新建一个new file
6,选择左侧Core Data
右边选择,NSManagedObject subclass,点击create
一路next,最后,自动生成book.h 和book.m
------------------------------------------------
7,点击工程左侧的model.xcdatamodeld,再点击中间的实体person,
最后点击右边的+加号,为person添加一个relationship
第2列的目标destination,选择下拉后的book
------------------------------------------------
5,选中model.xcdatamodeld右击,	新建一个new file
6,选择左侧Core Data
右边选择,NSManagedObject subclass,点击create
一路next,选择覆盖原来的person文件,
最后,自动生成person.h 和person.m
------------------------------------------------
8,现在还有问题,1人只能拥有1本书,解决方法:
点击工程左侧的model.xcdatamodeld,再点击中间的实体person,
最后点击,relationship,点击最右边的上方model inspector按钮
Type:一栏选择to many 而不是to one,并将name:一栏改成books回车
------------------------------------------------
5,再次重新:选中model.xcdatamodeld右击,	新建一个new file
6,选择左侧Core Data
右边选择,NSManagedObject subclass,点击create
一路next,选择覆盖原来的person文件,
最后,自动生成person.h 和person.m
------------------------------------------------
7,点击工程左侧的model.xcdatamodeld,再点击中间的实体book,
最后点击右边的+加号,为book添加一个relationship
第2列的目标destination,选择下拉后的person
第3列的目标inverse,选择下拉后的books
点击最右边的上方model inspector按钮
Type:一栏选择to many 而不是to one,意思1书 VS N person
------------------------------------------------
5,再次重新:选中model.xcdatamodeld右击,	新建一个new file
6,选择左侧Core Data
右边选择,NSManagedObject subclass,点击create
一路next,选择覆盖原来的person和book文件,
最后,自动生成person.h 和person.m,book.h 和book.m
------------------------------------------------
*/
@interface ViewController ()
{
// CoreData数据操作的上下文,负责所有的数据操作,
// 类似于SQLite的数据库连接句柄
NSManagedObjectContext *_context;
}
@end
/*
提示:开发过程中,如果对数据模型进行了调整,
一定记住删除沙箱中的数据库文件再继续调试。
*/
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// 1. 打开数据库
[self openDB];
// 2. 新增数据
[self addPerson];
// 3. 查询用户
[self allPersons];
// 4. 更新用户
[self updatePerson];
// 5. 删除记录
[self removePerson];
}
/**
*  打开数据库
*/
- (void)openDB
{
/*
回顾SQLite的操作方式(持久化)

1. opendb打开数据库,如果第一次运行,会在沙盒中创建数据库
2. 打开数据库之后,会生成一个数据库连接的句柄->_db,
后续的数据库操作均基于该句柄进行
3. 创建数据表(IF NOT EXISTS)

** Core Data的操作方式
1. 将所有定义好的数据模型文件合并成为一个数据模型(NSManagedObjectModel)
建立起针对实体对应的数据表的SQL语句,以便创建数据表
2. 用数据模型来创建持久存储的协调者,此时就具备了创建表的能力
3. 存储协调者关联 本地物理的持久化的数据存储(即SQLite数据库),
如果没有,新建并创建数据表
如果已经存在,直接打开数据库。

在打开数据库之后,会判断实体当前的结构与数据表的描述结构是否一致,
如果不一致,会提示打开失败!
*/
// 创建数据库
// 1. 实例化 自动生成的实体模型 (nil代表mainBundle,
//即将所有自动生成的那些定义了的实体模型都加载进来)
NSManagedObjectModel *model = [NSManagedObjectModel
mergedModelFromBundles:nil];
// 2. 实例化 持久存储的协调者,它建立起桥梁,需要的参数:自动生成的实体 模型
NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:model];
// 3. 存储协调者,开始关联物理数据库,通过物理数据库的fileURL
// 3.1 得到沙盒中数据库文件的绝对路径,并转成fileURL
NSArray *docs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *path = [docs[0] stringByAppendingPathComponent:@"my.db"];
NSURL *url = [NSURL fileURLWithPath:path];
// 3.2 打开或者新建数据库文件
// 如果文件不存在,则新建之后打开,否者直接打开数据库
NSError *error = nil;
// 桥梁,即协调者,上面已经关联了自动生成的实体模型,
// 现在,下面即将关联物理数据库,url形式,打开失败时,会输出错误信息到指定地址
[store addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil URL:url options:nil error:&error];
if (error) {
NSLog(@"打开数据库出错 - %@", error.localizedDescription);
} else {
NSLog(@"打开数据库成功!");
// 打开库,成功后,才对 上下文 实例化
_context = [[NSMnagedObjectContext alloc] init];
// 为上下文 成员 协调者,赋值
_context.persistentStoreCoordinator = store;
}
}
/**
新增个人记录
[NSEntityDescription insertNewObjectForEntityForName:@"Book"
inManagedObjectContext:_context];
*/
- (void)addPerson
{
/**
回顾SQL新增记录的过程
1. 拼接一个INSERT的SQL语句
2. 执行SQL
*/
// NSEntityDescription类的静态方法insertNewObjectForEntityForName()
//参数1:前面自动生成的实体名
//参数2:上下文
//返回值:id,代表可以插入任意类型

// 1. 实例化并让context“准备”将一条个人记录增加到数据库
Person *p = [NSEntityDescription insertNewObjectForEntityForName:@"Person"
inManagedObjectContext:_context];
// 2. 设置个人信息
p.name = @"张老头";
p.age = @10;
p.phoneNo = @"100";
// 将uiimage转成nsdata,UIImagePNGRepresentation,
p.image = UIImagePNGRepresentation([UIImage imageNamed:@"头像1"]);
// 3. 新增书,实例化并通知上下文准备加书
Book *b = [NSEntityDescription insertNewObjectForEntityForName:@"Book"
inManagedObjectContext:_context];
b.name = @"太极真经";
b.price = @20000.99;
b.author = @"太极忽悠";
Book *b2 = [NSEntityDescription insertNewObjectForEntityForName:@"Book"
inManagedObjectContext:_context];
b2.name = @"一阳神功";
b2.price = @0.99;
b2.author = @"老忽悠";
NSSet *bookSet = [NSSet setWithObjects:b, b2, nil];
// 1个人 拥有2本书
p.books = bookSet;
// 3. 保存(让context一次性保存当前的所有修改)
if ([_context save:nil]) {
NSLog(@"新增成功");
} else {
NSLog(@"新增失败");
}
}
/**
*  查询所有用户记录
*/
- (void)allPersons
{
// 1. 实例化一个查询(Fetch)请求
NSFetchRequest *request = [NSFetchRequest
fetchRequestWithEntityName:@"Person"];
// 3. 条件查询,通过谓词来实现的,谓词predicate?代表1个字符,*代表任意字符
//    request.predicate = [NSPredicate predicateWithFormat:@"age < 60 && name LIKE '*五'"];
// 在谓词中CONTAINS类似于数据库的 LIKE '%王%'
//    request.predicate = [NSPredicate predicateWithFormat:@"phoneNo CONTAINS '1'"];
// 如果要通过key path查询字段,需要使用%K,实质上是通过KVC来查询的
//    request.predicate = [NSPredicate predicateWithFormat:@"%K CONTAINS '1'", @"phoneNo"];
// 直接查询字表中的条件
// 2. 让_context执行查询数据 executeFetchRequest
NSArray *array = [_context executeFetchRequest:request error:nil];
for (Person *p in array) {
NSLog(@"%@ %@ %@", p.name, p.age, p.phoneNo);

// 在CoreData中,查询是懒加载的
// 在CoreData本身的SQL查询中,是不使用JOIN的,不需要外键
// 这种方式的优点是:内存占用相对较小,但是磁盘读写的频率会较高
for (Book *b in p.books) {
NSLog(@"%@ %@ %@", b.name, b.price, b.author);
}
}
//    for (Book *b in array) {
//        NSLog(@"%@ %@ %@", b.name, b.price, b.author);
//    }
}

/**
*  更新数据
*
*  在实际开发中,应该首先加载所有的数据,
绑定到UITableView中,该数组中保存所有的Person记录,
*  如果是这种情况,在修改个人记录时,是无需再次去查询数据库的。
*
*  在实际开发中,通常是从表格中选中某一行,
获取到对应的NSManagedObject????,然后进行修改
*  如此,便可以只修改唯一一条记录了。
*/
- (void)updatePerson
{
// 1. 实例化查询请求
NSFetchRequest *request = [NSFetchRequest
fetchRequestWithEntityName:@"Book"];
// 2. 设置谓词条件
request.predicate = [NSPredicate
predicateWithFormat:@"author CONTAINS '大忽悠'"];
// 3. 由上下文查询数据
NSArray *result = [_context executeFetchRequest:request error:nil];
// 4. 输出结果
for (Book *book in result) {
NSLog(@"%@ %@ %@", book.name, book.author, book.price);

// 更新书名
book.name = @"西游记";
}
// 通知上下文保存保存
[_context save:nil];
}
#pragma mark - 数据库操作方法
/**
*  删除记录
*/
- (void)removePerson
{
// 1. 实例化查询请求
NSFetchRequest *request = [NSFetchRequest
fetchRequestWithEntityName:@"Person"];
// 2. 设置谓词条件
request.predicate = [NSPredicate
predicateWithFormat:@"name = '张老头'"];
// 3. 由上下文查询数据
NSArray *result = [_context
executeFetchRequest:request error:nil];
// 4. 输出结果
for (Person *person in result) {
NSLog(@"%@ %@ %@", person.name, person.age, person.phoneNo);

// 删除一条记录    deleteObject方法的参数是:NSManagedObject *
[_context deleteObject:person];
break;
}
// 5. 通知_context保存数据
if ([_context save:nil]) {
NSLog(@"删除成功");
} else {
NSLog(@"删除失败");
}
}
@end

H:/1125/01_CoreData_Xcode生成_Book.h
//  Book.h
//  CoreData演练
//  Created by apple on 13-11-25.
//  Copyright (c) 2013年 itcast. All rights reserved.
//  Xcode自动生成
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class Person;
@interface Book : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * price;
@property (nonatomic, retain) NSString * author;
@property (nonatomic, retain) NSSet *persons;
@end
// 分类扩展 CoreDataGeneratedAccessors
@interface Book (CoreDataGeneratedAccessors)
- (void)addPersonsObject:(Person *)value;
- (void)removePersonsObject:(Person *)value;
- (void)addPersons:(NSSet *)values;
- (void)removePersons:(NSSet *)values;
@end

H:/1125/01_CoreData_Xcode生成_Book.m
//  Book.m
//  CoreData演练
//  Created by apple on 13-11-25.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import "Book.h"
#import "Person.h"
//  Xcode自动生成
@implementation Book
@dynamic name;
@dynamic price;
@dynamic author;
@dynamic persons;
@end

H:/1125/01_CoreData_Xcode生成_Person.h
//  Person.h
//  CoreData演练
//  Created by apple on 13-11-25.
//  Copyright (c) 2013年 itcast. All rights reserved.
//  Xcode自动生成
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class Book;
@interface Person : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * age;
@property (nonatomic, retain) NSString * phoneNo;
@property (nonatomic, retain) NSData * image;
@property (nonatomic, retain) NSSet *books;
@end
// 分类扩展CoreDataGeneratedAccessors
@interface Person (CoreDataGeneratedAccessors)
- (void)addBooksObject:(Book *)value;
- (void)removeBooksObject:(Book *)value;
- (void)addBooks:(NSSet *)values;
- (void)removeBooks:(NSSet *)values;
@end

H:/1125/01_CoreData_Xcode生成_Person.m
//  Person.m
//  CoreData演练
//  Created by apple on 13-11-25.
//  Xcode自动生成
#import "Person.h"
#import "Book.h"
@implementation Person
@dynamic name;
@dynamic age;
@dynamic phoneNo;
@dynamic image;
@dynamic books;
@end

H:/1125/02_CoreData笔记.txt

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  IOS 数据存储 CoreData