欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

XMPP框架 微信项目开发之CoreData学习——CoreData的多表关联操作

程序员文章站 2022-06-15 20:10:09
...

多表关联时需要注意的问题:

问题一:如果需要在原来工程的基础上新添功能(即新增实体),需要删除原先的数据库和原先生成的实体类。因为表结构发生了改变 其对应的实体类和数据库也都需要改变。所以要删除重新生成。

问题二:在生成实体类的时候,是有先后顺序的,需要先生成那些只具有基本属性的非嵌套的实体类,然后再生成以这些只具备简单属性实体类对象为成员的嵌套实体类。

多表关联还涉及一对一、一对多、以及级联cascade操作,这些在模板内都可直接勾选实现。

多表关联在创建实体对象时,需要先创建成员对象,然后使用创建的实体成员对象给自身的成员属性赋值即可。

多表查询时使用谓词查询 直接使用点语法(.)即可如下所示:

NSPredicate *predicate = [NSPredicatepredicateWithFormat:@"depart.name = %@",@"ios"];

新建工程,具体实现步骤如下:

步骤一:增添部门实体,并为员工实体添加部门成员属性。

XMPP框架 微信项目开发之CoreData学习——CoreData的多表关联操作

删除以前生成的员工实体生成的对应实体类,并先生成只具备简单属性的非嵌套实体部门实体类。

XMPP框架 微信项目开发之CoreData学习——CoreData的多表关联操作

生成部门类后,再生成以部门类为成员的员工实体类。

XMPP框架 微信项目开发之CoreData学习——CoreData的多表关联操作

生成的实体类如下所示:

部门实体类

<span style="font-size:18px;">//
//  Department.h
//  CoreData的简单使用
//
//  Created by apple on 15/11/2.
//  Copyright (c) 2015年 LiuXun. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>


@interface Department : NSManagedObject

@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * departNo;
@property (nonatomic, retain) NSDate * createDate;

@end</span>
<span style="font-size:18px;">//
//  Department.m
//  CoreData的简单使用
//
//  Created by apple on 15/11/2.
//  Copyright (c) 2015年 LiuXun. All rights reserved.
//

#import "Department.h"


@implementation Department

@dynamic name;
@dynamic departNo;
@dynamic createDate;

@end</span>
员工实体类

<span style="font-size:18px;">//
//  Employee.h
//  CoreData的简单使用
//
//  Created by apple on 15/11/2.
//  Copyright (c) 2015年 LiuXun. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class Department;

@interface Employee : NSManagedObject

@property (nonatomic, retain) NSDate * birthday;
@property (nonatomic, retain) NSNumber * height;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) Department *depart;

@end</span>


<span style="font-size:18px;">//
//  Employee.m
//  CoreData的简单使用
//
//  Created by apple on 15/11/2.
//  Copyright (c) 2015年 LiuXun. All rights reserved.
//

#import "Employee.h"
#import "Department.h"


@implementation Employee

@dynamic birthday;
@dynamic height;
@dynamic name;
@dynamic depart;

@end</span>
在控制器代码编辑如下:

<span style="font-size:18px;">//
//  ViewController.m
//  CoreData的简单使用
//
//  Created by apple on 15/11/2.
//  Copyright (c) 2015年 LiuXun. All rights reserved.
//

#import "ViewController.h"
#import "Employee.h"
#import "Department.h"
#import <CoreData/CoreData.h>
@interface ViewController ()
@property(nonatomic, strong)NSManagedObjectContext *context;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    /**
     1. 创建模型文件(相当于数据库里的一张关系表)
     2. 添加实体(与一个对象相对应)
     3. 创建实体类(相当于模型)
     4. 生成上下文 关联模型文件生成数据库
     : 注意:关联的时候,如果本地没有数据库文件,coreData自己会创建。
     */
    // 上下文是专门用来管理实体对象的
    NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
    
    // 关联数据库——参数传为nil,意味着从所有的模板xcdatamodeld进行读取
    NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
    
    // 持久化存储助理(调度器)
    // 持久化,把数据保存到一个文件里,而不是内存
    NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
    
    // 告诉Coredata数据库的名称和路径
    NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *sqlitePath = [doc stringByAppendingPathComponent:@"company.sqlite"];
    NSLog(@"%@", sqlitePath);
    [store addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:sqlitePath]  options:nil error:nil];
    
    
    context.persistentStoreCoordinator = store;
    _context = context;
    
//        [self addEmployee];
        [self readEmployee];
    //    [self updateEmployee];
//    [self deleteEmployee];
}

// 数据库的操作  CURD — Create Update Read Delete  对记录进行增删改查

#pragma mark 添加员工
-(void)addEmployee
{
    // 创建两个部门 IOS Android
    Department *iosDepart = [NSEntityDescription insertNewObjectForEntityForName:@"Department" inManagedObjectContext:self.context];
    iosDepart.name = @"ios";
    iosDepart.departNo = @"0001";
    iosDepart.createDate = [NSDate date];
    
    Department *androidDepart = [NSEntityDescription insertNewObjectForEntityForName:@"Department" inManagedObjectContext:self.context];
    androidDepart.name = @"android";
    androidDepart.departNo = @"0002";
    androidDepart.createDate = [NSDate date];

    
    // 创建一个员工对象  张三 属于IOS部门  李四属于Android部门
    Employee *emp = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:self.context];
    emp.name = @"张三";
    emp.height = @(1.85);
    emp.birthday = [NSDate date];
    emp.depart = iosDepart;
    
    Employee *emp2 = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:self.context];
    emp2.name = @"李四";
    emp2.height = @(1.75);
    emp2.birthday = [NSDate date];
    emp2.depart = androidDepart;
    
     NSError *error;
    [self.context save:&error];
    if (error) {
        NSLog(@"%@", [error localizedDescription]);
    }
}

#pragma mark 读取员工
-(void)readEmployee
{
    /**
    读取IOS部门的员工
     */
    
    // 1. FetchRequest 抓取请求对象
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
    
    // 2. 设置过滤请求条件
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"depart.name = %@", @"ios"];
    request.predicate = predicate;
    
       // 4. 执行请求
    NSError *error = nil;
    NSArray *employees = [self.context executeFetchRequest:request error:&error];
    if (error) {
        NSLog(@"error");
    }
    for (Employee *emp  in employees) {
        NSLog(@"名称:%@  部门%@", emp.name, emp.depart.name);
    }
}

#pragma mark 更新员工
-(void)updateEmployee
{
    // 1 修改张三的身高为2米
    
    // 查找张三
    // 1.1  FetchRequest 抓取请求对象
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
    
    // 1.2 设置过滤请求条件
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name=%@", @"张三"];
    request.predicate = predicate;
    
    // 1.3 执行请求
    NSArray *employees = [self.context executeFetchRequest:request error:nil];
    
    // 2. 更新身高
    for (Employee *e in employees) {
        e.height = @2.0;
    }
    
    // 保存
    [self.context save:nil];
    
    for (Employee *emp  in employees) {
        NSLog(@"名称 %@ 身高 %@ 生日 %@", emp.name, emp.height, emp.birthday);
    }
    
}

#pragma mark 删除李四
-(void) deleteEmployee{
    // 删除李四
    // 1. 查找李四
    // 查找张三
    // 1.1  FetchRequest 抓取请求对象
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
    
    // 1.2 设置过滤请求条件
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name=%@", @"李四"];
    request.predicate = predicate;
    
    // 1.3 执行请求
    NSArray *employees = [self.context executeFetchRequest:request error:nil];
    
    // 2. 删除
    for (Employee *e in employees) {
        [self.context deleteObject:e];
    }
    
    // 3. 保存
    [self.context save:nil];
}


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

@end</span>

运行结果如下:

XMPP框架 微信项目开发之CoreData学习——CoreData的多表关联操作

XMPP框架 微信项目开发之CoreData学习——CoreData的多表关联操作