XMPP框架 微信项目开发之CoreData学习——CoreData的多表关联操作
程序员文章站
2022-06-15 20:10:09
...
多表关联时需要注意的问题:
问题一:如果需要在原来工程的基础上新添功能(即新增实体),需要删除原先的数据库和原先生成的实体类。因为表结构发生了改变 其对应的实体类和数据库也都需要改变。所以要删除重新生成。
问题二:在生成实体类的时候,是有先后顺序的,需要先生成那些只具有基本属性的非嵌套的实体类,然后再生成以这些只具备简单属性实体类对象为成员的嵌套实体类。
多表关联还涉及一对一、一对多、以及级联cascade操作,这些在模板内都可直接勾选实现。
多表关联在创建实体对象时,需要先创建成员对象,然后使用创建的实体成员对象给自身的成员属性赋值即可。
多表查询时使用谓词查询 直接使用点语法(.)即可如下所示:
NSPredicate *predicate = [NSPredicatepredicateWithFormat:@"depart.name = %@",@"ios"];
新建工程,具体实现步骤如下:步骤一:增添部门实体,并为员工实体添加部门成员属性。
删除以前生成的员工实体生成的对应实体类,并先生成只具备简单属性的非嵌套实体部门实体类。
生成部门类后,再生成以部门类为成员的员工实体类。
生成的实体类如下所示:
部门实体类
<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>
运行结果如下: