IOS_数据存储之CoreData

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
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值