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

iOS讲解迷惑之Core Data

2015-10-16 08:34 387 查看
一、概念 Core Data相当于封装了sqlite

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

2.数据最终的存储类型可以是:SQLite数据库,XML,二进制,内存里,或自定义数据类型
core Data存储的路径格式是URL类型
sqlite 存储的路径格式是 string类型

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

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

4.构成:

(1)NSManagedObjectContext(被管理的数据上下文, 就是临时数据库 增删改查就是操作的临时DB)

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

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

(2)NSManagedObjectModel(被管理的数据模型, 比如Student)

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

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

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

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

相当于数据库的连接器

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

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

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

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

相当于查询语句

(6)NSEntityDescription(实体结构)

相当于表格结构

(7)后缀为.xcdatamodeld的包

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

编译后为.momd或.mom文件

创建Core Data的步骤
创建单表步骤
1. cmd + shift + N 创建工程, 要勾选
Use Core Data

3. cmd + N 添加NSManagedObject subclass (被管理对象子类)

next 创建成对象

NSFetchRequest
[b]描述搜索条件的一个实例用于从持久存储中检索数据。




NSEntityDescription

对象描述了一个实体的核心数据。实体管理对象类是什么id,或者使用一个数据库analogy-what表行。实例指定一个实体的名字,其属性(属性和关系,表达了NSAttributeDescriptionNSRelationshipDescription)的实例和类的代表。



NSPredicate

类是用于定义逻辑条件用于限制搜索获取或者内存筛选[/b]


示例代码

<span style="font-size:14px;">//
//  ViewController.m
//  CoreData-01
//
//  Created by  on 15/10/9.
//  Copyright (c) 2015年 nieyinlong. All rights reserved.
//

#import "ViewController.h"
#import "AppDelegate.h" // 引入头文件 进行懒加载 NSManagedObjectContext
#import "Student.h"  // 导入学生对象
@interface ViewController ()

#pragma mark---- 属性声明 被管理对象上下文(临时数据库)
@property (nonatomic, strong) NSManagedObjectContext *managerContext;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

#pragma mark--- 添加 (操作的是临时DB)
- (IBAction)addBtnAction:(id)sender {
    //NSLog(@"添加");
    
    // 1. 创建实体描述
    // entityForName: 实体名
    NSEntityDescription *studentDB = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:self.managerContext];
    
    // 循环添加实体 (也就是给临时数据库的学生数据表添加一条条信息)
    for (int i = 0; i < 10; i++) {
        // 2. 根据实体描述创建实体
        Student *student = [[Student alloc] initWithEntity:studentDB insertIntoManagedObjectContext:self.managerContext];
        // 3. 给实体赋值
        student.name = [NSString stringWithFormat:@"军军%d号", i];
        student.sex = [NSString stringWithFormat:@"男"];
        student.age = [NSNumber numberWithInt:18 + i];
    } // 循环结束就是添加了十条数据
    
// 添加单条数据
/*
    // 2. 根据实体描述创建实体
    Student *student = [[Student alloc] initWithEntity:studentDB insertIntoManagedObjectContext:self.managerContext];
    // 3. 给实体赋值
    student.name = [NSString stringWithFormat:@"军军1号"];
    student.sex = [NSString stringWithFormat:@"男"];
    student.age = [NSNumber numberWithInt:18];
 */
    
    // 添加到临时数据库以后需要同步到file
    NSError *error = nil;
    [self.managerContext save:&error]; // 同步
    if (!error) {
        NSLog(@"存储成功");
    }

    
}

#pragma mark--- 查询
- (IBAction)selectBtnAction:(UIButton *)sender {
 
    
    // 用实体名 初始化一个 获取请求
    NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Student"];
    // 创建实体描述
    NSEntityDescription *studentDB = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:self.managerContext];
    // 给获取请求设置实体
    request.entity = studentDB;
    
    /**
     *  数组接收查询的数据
     *  @param NSFetchRequest 请求
     *  @return 查询后的数组
     */
    NSArray *array = [self.managerContext executeFetchRequest:request error:nil];
    
    // 便利数组  (没有限定范围, 查询全部)
    for (Student *stu in array) {
        NSLog(@"查询全部: 姓名:%@, 年龄:%@, 性别:%@", stu.name, stu.age, stu.sex); // 打印结果是无序的
    }
    
    // 按年龄排序
    // YES 代表升序 NO是降序
    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"age" ascending:YES];
    // 把排序好的数组放进 request.sortDescriptors
    request.sortDescriptors = @[sort];
    
    
    
//------------------------------------------------------------------------------------
//-------- 开始按照谓词条件 查询 (限定范围) ---------------------------------------------------------
    
    // 设置查询 根据指定条件查询 (相当于sql语句) // Predicate 代表陈述语句
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@", @"军军8号"];
    
    // 查询包含 "8" 的 学生信息 (模糊查询)
//    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name CONTAINS %@", @"8"];
    
    // 查询后面的几个字符未知的信息 (模糊查询)
    //NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name LIKE %@", @"军军*"];
    // 给请求加 陈述语句
    request.predicate = predicate;
    
    /*// 连写
     request.predicate = [NSPredicate predicateWithFormat:@"name = %@", @"张三"];*/
    
    // 利用设置好的请求条件取出临时数据库中的对应的数据
    NSArray *preArray = [self.managerContext executeFetchRequest:request error:nil];
    // 便利数组
    for (Student *stu in preArray) {
        NSLog(@"按谓词条件查询的结果: 姓名:%@, 年龄:%@, 性别:%@", stu.name, stu.age, stu.sex); // 打印结果是: 按谓词条件查询的结果: 姓名:军军8号, 年龄:26, 性别:男
    }
    
    
    // 数据同步
    NSError *error = nil;
    [self.managerContext save:&error];
    if (!error) {
        NSLog(@"查询成功");
    }
}

#pragma mark--- 修改
- (IBAction)updateBtnAction:(UIButton *)sender {

    // 用实体名 初始化一个 获取请求
    NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Student"];
    
    // 创建实体描述
    NSEntityDescription *studentDB = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:self.managerContext];
    // 给请求设置实体描述
    request.entity = studentDB;
    
    // 这里连写等效于以上两步
    // request.entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:self.managerContext];
    
    
    // 设置谓词条件 (修改的限定范围是性别为男的学生)
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"sex = %@", @"男"];
    request.predicate = predicate; // 把设置好的谓词条件赋值给 NSFetchRequest类的predicate属性
    
    
    // 接收查询的数据 , 根据设置好的请求 查询临时数据库(上下文) , 此时的道的数组就是sex = 男的全部信息
    NSArray *array = [self.managerContext executeFetchRequest:request error:nil];
    
    // 遍历查询后的数据
    for (Student *stu in array) {
        stu.name = [NSString stringWithFormat:@"军军9999999号"]; // 把性别为男的 名字为"军军8号"的学生的姓名改为: "军军1000000号"
        NSLog(@"修改后: %@, %@, %@", stu.name, stu.age, stu.sex);
    }
    
    NSError *error = nil;
    [self.managerContext save:&error];
    if (!error) {
        NSLog(@"修改成功");
    }
}

#pragma mark--- 删除
- (IBAction)delecteBtnAction:(UIButton *)sender {

    
    // 请求
    NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Student"];
    
    // 实体描述
    NSEntityDescription *studentDB = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:self.managerContext];
    // 设置查询实体
    request.entity = studentDB;
    
   // 谓词条件 (限定要删除的条件)
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@", @"军军2号"];
    request.predicate = predicate; // 给请求添加谓词条件
    
    // 连写 等效于上面的两句
    // request.predicate = [NSPredicate predicateWithFormat:@"name = %@", @"军军2号"];
    
    
    /**
     *  根据设置好的请求查找临时数据库 返回一个数组
     *  @param NSFetchRequest 请求
     *  @return 查询后的数组
     */
    NSArray *array = [self.managerContext executeFetchRequest:request error:nil]; // 此时数组存储了name = 军军2号的数据
    
    // 遍历查询后的数组
    for (Student *stu in array) {
      [self.managerContext deleteObject:stu]; // 删除 name = 军军2号 的那条数据
        NSLog(@"%@%@%@", stu.name, stu.age, stu.sex);
    }

    
    // 同步
    NSError *error = nil;
    [self.managerContext save:&error];
    if (!error) {
        NSLog(@"删除成功");
    }
}

#pragma mark---- 被管理对象上下文的懒加载方法
- (NSManagedObjectContext *)managerContext
{
    if (!_managerContext) {
        
        // 获取Appdelegate当中的被管理对象上下文(临时DB)
        _managerContext =  ((AppDelegate *)[UIApplication sharedApplication].delegate).managedObjectContext;
    }
    return _managerContext;
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];

}

@end</span><span style="font-size: 24px;">
</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: