Core Data基本使用(附两表关联Demo)

2018-10-16  本文已影响0人  cocoaCoffee

前言

   对于许多应用来说,需要将本地保存和获取的数据持久化用在其他会话中。从ios3.0开始,Core Data就负责完成这项工作。Core Data是一个非常强大的对象数据库,提供了非常健壮的数据存储和管理功能,和java EE的MyBetis有点类似,都是对数据持久化封装的框架,Core Data是对SQLite的封装,是SQLite的轻量版

特性

Demo描述

  有两张表,这样既可以学会基础的增删查改,也可以知道多表之间的操作,下面可能比较基础

创建项目

image.png

这个我们可以先别选,因为做项目的时候你怎么知道要用Core Data,然后我们自己手动创建一个文件,command+N


image.png

创建成功就会多出一个.xcdatamodeld的文件,这个就是模型文件,注意这不是底层数据库,只是数据库的映射吧,点击这个文件看看


Snip20181016_2.png

点击Add Entity创建两个实体(实体名称首字母必须大写),学生实体和课程实体,学生有三个属性,课程有两个属性,关系是多对多关系,一个学生可以有多门课程,一门课程可以多个学生学习,先看下那个lentstudent这个相当于外键的名称吧,第二个就是关联哪张表,第三个就是逆,即你在关联哪张表的关联名称,也就是说你在Cousre实体关联Student实体的关联名称是lentstudent,那个Inverse是lentcourse,那么你在在Student实体关联Cousre实体的关联名称是lentsourse

选中关系看右边 image.png

to many就是对多咯,你想要多对多就是两张表都设置成to many就多对多了

把这些都搞完了,就要创建实体模型的类了,就相当于plist文件,你要创建一个模型类。

core data创建实体的模型类,xcode会帮你做,直接点就行了,选中
.xcdatamodeld文件,然后看图


image.png
image.png

点完后就会多出这几个实体类,你想用那个实体引用头文件就行


image.png

接下来我们去storyboard上拉四个按钮,简单地修改他的约束,在把他们的单击事件拉到控制器

image.png
image.png

接下来记住几个Core Data类名

首先看下Demo的头文件

image.png

首先肯定要有coredata的头文件,你要用什么实体(表)就添加什么实体的这个类


image.png

第一步 创建数据库

   这里的数据库是指底层的SQLite,这里写个方法,没有直接帮你创建这个名字的sqlite数据库,我们先创建一个管理上下文的对象

 //用来管理上下文的对象
NSManagedObjectContext * _context;

再写创建数据库的方法

//创建数据库
- (void)creatsqlite
{
//1、创建模型对象
//获取模型路径
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
//根据模型文件创建模型对象
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];



//2、创建持久化存储助理:数据库
//利用模型对象创建助理对象
NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];

//数据库的名称和路径
NSString *docStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *sqlPath = [docStr stringByAppendingPathComponent:@"sqlite.sqlite"];
NSLog(@"数据库 path = %@", sqlPath);
NSURL *sqlUrl = [NSURL fileURLWithPath:sqlPath];

NSError *error = nil;
//设置数据库相关信息 添加一个持久化存储库并设置存储类型和路径,NSSQLiteStoreType:SQLite作为存储库
[store addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:sqlUrl options:nil error:&error];

if (error) {
    NSLog(@"添加数据库失败:%@",error);
} else {
    NSLog(@"添加数据库成功");
}

//3、创建上下文 保存信息 操作数据库

NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

//关联持久化助理
context.persistentStoreCoordinator = store;

_context = context;

}

这里为什么获取模型文件的时候是momd而不是xcdatamodeld
因为初始化必须依赖.momd文件路径,而.momd文件由.xcdatamodeld文件编译而来

跑一下工程

image.png

这个路径就会多出一个叫sqlite的数据库,自己可以根据给出的路径去找下,查看隐藏文件夹快捷键shift+cmmand+.

第二步 插入数据

//增
- (IBAction)insertData {

// 1.根据Entity名称和NSManagedObjectContext获取一个新的继承于NSManagedObject的子类Student

//  2 根据表Course中的键值,给NSManagedObject对象赋值

Course *course1 = [NSEntityDescription
                   insertNewObjectForEntityForName:@"Course"
                   inManagedObjectContext:_context];
course1.name = @"iOS";
course1.creatdate = [NSDate date];

Course *course2 = [NSEntityDescription
                   insertNewObjectForEntityForName:@"Course"
                   inManagedObjectContext:_context];
course2.name = @"Android";
course2.creatdate = [NSDate date];

//  3 同上操作

Student *student1 = [NSEntityDescription
                     insertNewObjectForEntityForName:@"Student"
                     inManagedObjectContext:_context];
student1.name = @"张三";
student1.birthday = [NSDate date];
//student1.lentcourse = course1;
[student1 addLentcourseObject:course1];

Student *student2 = [NSEntityDescription
                     insertNewObjectForEntityForName:@"Student"
                     inManagedObjectContext:_context];
student2.name = @"李四";
student2.birthday = [NSDate date];
[student2 addLentcourseObject:course2];


//   4.保存插入的数据
NSError *error = nil;
if ([_context save:&error]) {
    NSLog(@"数据插入到数据库成功");
}else{

    NSLog(@"数据插入到数据库失败, %@",error);
}
}
-(void)addLentcourseObject:(Course *)value;

这个方法返回才是Course类的

写完这个方法我们再跑下,看下他有没有添加数据进去了,可以用这个软件看下这个数据库


image.png

点击插入


image.png
加进来了
image.png

第三步 查询数据

//查
- (IBAction)queryData {
//1:FectchRequest 抓取请求对象
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
//2:设置过滤条件  这里我们查询选了iOS课的学生信息
NSPredicate *pre = [NSPredicate predicateWithFormat:@"ANY lentcourse.name = %@",@"iOS"];
request.predicate = pre;
//3:设置排序
//    NSSortDescriptor *height = [NSSortDescriptor sortDescriptorWithKey:@"height" ascending:YES];
//    request.sortDescriptors = @[height];

//4:执行请求
NSArray *message = [_context executeFetchRequest:request error:nil];
//遍历查询结果
for (Student *student in message) {
    NSLog(@"名字:%@,生日:%@",student.name,student.birthday);
}



}
iOS课程是张三在学习

第四步 删除

//删
- (IBAction)deleteData {
//1:先查询到需要删除的数据(比如这里以删除员工张三的数据为例)
//1.1:FectchRequest 抓取请求对象
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
//1.2:设置过滤条件
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name = %@",@"张三"];
request.predicate = pre;
//1.3执行查询请求
NSArray *message = [_context executeFetchRequest:request error:nil];
//2:执行删除操作
for (Student *student in message) {
    [_context deleteObject:student];
}

//3:保存
[_context save:nil];
}

点击删除,张三没了


image.png

第五步 修改

//改
- (IBAction)upDateData {
//1:先查询出需要更新的数据
//1.1:FectchRequest 抓取请求对象
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
//1.2:设置过滤条件
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name = %@",@"李四"];
request.predicate = pre;
//1.3执行查询请求
NSArray *message = [_context executeFetchRequest:request error:nil];

//2:更新数据
for (Student *student  in message) {
    student.name = @"王五";
}
//3:保存
[_context save:nil];

}
image.png
/* 谓词的条件指令
 1.比较运算符 > 、< 、== 、>= 、<= 、!=
 例:@"number >= 99"

 2.范围运算符:IN 、BETWEEN
 例:@"number BETWEEN {1,5}"
 @"address IN {'shanghai','nanjing'}"

 3.字符串本身:SELF
 例:@"SELF == 'APPLE'"

 4.字符串相关:BEGINSWITH、ENDSWITH、CONTAINS
 例:  @"name CONTAIN[cd] 'ang'"  //包含某个字符串
 @"name BEGINSWITH[c] 'sh'"    //以某个字符串开头
 @"name ENDSWITH[d] 'ang'"    //以某个字符串结束

 5.通配符:LIKE
 例:@"name LIKE[cd] '*er*'"   // *代表通配符,Like也接受[cd].
 @"name LIKE[cd] '???er*'"

 *注*: 星号 "*" : 代表0个或多个字符
 问号 "?" : 代表一个字符

6.正则表达式:MATCHES
 例:NSString *regex = @"^A.+e$"; //以A开头,e结尾
 @"name MATCHES %@",regex

 注:[c]*不区分大小写 , [d]不区分发音符号即没有重音符号, [cd]既不    区分大小写,也不区分发音符号。

 7. 合计操作
 ANY,SOME:指定下列表达式中的任意元素。比如,ANY     children.age < 18。
 ALL:指定下列表达式中的所有元素。比如,ALL children.age < 18。
 NONE:指定下列表达式中没有的元素。比如,NONE children.age < 18。它在逻辑上等于NOT (ANY ...)。
 IN:等于SQL的IN操作,左边的表达必须出现在右边指定的集合中。比如,name IN { 'Ben', 'Melissa', 'Nick' }。

 提示:
 1. 谓词中的匹配指令关键字通常使用大写字母
 2. 谓词中可以使用格式字符串
 3. 如果通过对象的key
 path指定匹配条件,需要使用%K

 */

因为才看了网上很多文章写出来的,绝对是取其精华的,有些文章比我的还水,有些观点也是我自己的观点,我也是一名菜鸟,希望有错能指出,相互学习

最后附上源码地址:Demo Github地址

上一篇下一篇

猜你喜欢

热点阅读