一、CoreData的简单使用
1.什么是CoreData
先认识一下这几个类
(1)NSManagedObjectContext(被管理的数据上下文)
作用:用来管理所有表的操作,对表的实体对应的数据库中的表的操作(插入,查询,修改,删除)
(2)NSManagedObjectModel(被管理的数据模型,对应.momd文件)
数据库所有表格或数据结构,包含各实体的定义信息
作用:添加实体的属性,建立属性之间的关系
(3)NSPersistentStoreCoordinator(数据库的连接器,持久化存储助理)
作用:用来管理数据库的,可以设置数据存储的名字,位置,存储方式,和存储时机
(4)NSManagedObject(被管理的数据记录)
相当于数据库中的表格记录
(5)NSFetchRequest(获取数据的请求)
相当于查询语句
(6)NSEntityDescription(实体结构对应单个表)
相当于表结构
(7)后缀为.xcdatamodeld的包(CoreData的模型文件)
数据模型编辑器编译后为.momd或.mom文件
作用:描述app中的所有实体和实体属性
2.CoreData的使用步骤
3.创建公司模型文件并创建员工实体Employee(name,age,height)
1)创建模型文件(相对于数据库)
2)创建实体文件(相对于表结构)
并添加相应字段
- 3.创建实体类 相于模型类 (next选择模型文件,并关联表)
- 4.生成上下文 关联模型文件生成数据库
NSManagedObjectContext *ctx = [[NSManagedObjectContextalloc]init];
//传一个nil,会把当前bundle的文件都关联起来
NSManagedObjectModel *model = [NSManagedObjectModelmergedModelFromBundles:nil];
NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)lastObject];
NSString *sqlPath = [docstringByAppendingPathComponent:@"company.sqlite"];
// 持久化存储调度器
NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinatoralloc]initWithManagedObjectModel:model];
ctx.persistentStoreCoordinator = store;
NSError *error = nil;
[store addPersistentStoreWithType:NSSQLiteStoreTypeconfiguration:nilURL:[NSURLfileURLWithPath:sqlPath]options:nilerror:&error];
self.context = ctx;
5.保存员工数据
//创建员工 通过表结构NSEntityDescription
Employee *employ = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:self.context];
//设置员工属性
employ.name = @"王五";
employ.age = @29;
employ.height = @1.79;
NSError *error = nil;
[self.context save:&error];
if (!error) {
NSLog(@"插入成功");
}
6.读取员工数据
NSError *error = nil;
NSArray *emps = [self.context executeFetchRequest:request error:&error];
if (!error) {
NSLog(@"emps: %@",emps);
for (Employee *emp in emps) {
NSLog(@"%@ %@ %@",emp.name,emp.age,emp.height);
}
}else{
NSLog(@"%@",error);
}
*> 读取张三的员工信息
1)直接遍历出所有对象进行查询
// 修改数据必须要先把数据查询出来,然后再修改
for (Person *p in emps) {
//如果是“zhangsan”,则修改他的年龄为18
if ( [p.name isEqualToString:@"zhangsan"] ) {
p.age = [NSNumber numberWithInt:18];
}
}
//保存。修改数据
[self.managedObjectContext save:nil];
2)创建请求体 过滤查询
//创建一个请求对象 (填入要查询的表名-实体类)
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
// 过滤查询
// 查找张三 并且身高大于1.8
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name=%@ AND height > %@",@"zhangsan",@(1.8)];
request.predicate = pre;
*> 身高排序
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"height" ascending:YES];
request.sortDescriptors = @[sort];
6.修改员工数据
*> 修改张三的身高
// 1.查找员工
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name=%@",name];
request.predicate = pre;
NSArray *emps =[self.context executeFetchRequest:request error:nil];
if (emps.count == 1) {
Employee *emp = emps[0];
emp.height = @1.7;
}
// 3.同步(保存)到数据
[self.context save:nil];
7.删除员工数据
// 删除zhangsan
// 1.查找到zhangsan
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name=%@",name];
request.predicate = pre;
// 2.删除zhangsan
NSArray *emps = [self.context executeFetchRequest:request error:nil];
for (Employee *emp in emps) {
NSLog(@"删除员工的人 %@",emp.name);
[self.context deleteObject:emp];
}
// 3.用context同步下数据库
//所有的操作暂时都是在内存里,调用save 同步数据库
[self.context save:nil];
8.模糊查询
// 查询
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
// 过滤
// 1.查询以wang开头员工
//NSPredicate *pre = [NSPredicate predicateWithFormat:@"name BEGINSWITH %@",@"wang"];
// 2.以si 结尾
//NSPredicate *pre = [NSPredicate predicateWithFormat:@"name ENDSWITH %@",@"si"];
// 3.名字包含 g
// NSPredicate *pre = [NSPredicate predicateWithFormat:@"name CONTAINS %@",@"g"];
// 4.like 以si结尾
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name like %@",@"li*"];
request.predicate = pre;
//读取信息
NSError *error = nil;
NSArray *emps = [self.context executeFetchRequest:request error:&error];
if (!error) {
NSLog(@"emps: %@",emps);
for (Employee *emp in emps) {
NSLog(@"%@ %@ %@",emp.name,emp.age,emp.height);
}
}else{
NSLog(@"%@",error);
}
二、高级查询
//c表示不区分大小写
// like '*jp'" //以jp结束
//@"name BEGINSWITH[cd] '李'" //姓李的员工
//@"name ENDSWITH[c] '梦'" //以梦结束的员工
//@"name CONTAINS[d] '宗'" //包含有"宗"字的员工
//分页fetchOffset fetchBatchSize
// 分页查询 每页显示5条数据
//第一页的数据
request.fetchLimit = 5; //每页显示5条数据
request.fetchOffset = 0;//起始数据
三、查找多表关联
1>添加部门表,查询属于某个部门的员工
创建部门实体文件,表结构(这里不截图了)记得和员工表格进行关联
// 1.添加zhangsan 属于ios部门
Employee *emp1 = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:self.context];
emp1.name = @"zhangsan";
emp1.height = @1.7;
emp1.age = @27;
// 创建ios部门
Department *dep1 = [NSEntityDescription insertNewObjectForEntityForName:@"Department" inManagedObjectContext:self.context];
dep1.name = @"ios";//部门
dep1.createDate = [NSDate date];//部门创建时间
dep1.departNo = @"D001";//部门编号
emp1.depart = dep1;
//查找ios部门的员工
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
// 过滤查询
NSPredicate *pre = [NSPredicate predicateWithFormat:@"depart.name = %@",@"ios"];
request.predicate = pre;
//读取信息
NSError *error = nil;
NSArray *emps = [self.context executeFetchRequest:request error:&error];
if (!error) {
NSLog(@"emps: %@",emps);
for (Employee *emp in emps) {
NSLog(@"name:%@ departName:%@ ",emp.name,emp.depart.name);
}
}else{
NSLog(@"%@",error);
}
备注:Cocoa框架中的NSPredicate用于查询,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取。
四、多个model文件,多个context;
在新建一个数据库实体文件,并关联实体类
// 1.上下文 关联Company.xcdatamodeld 模型文件
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
// 关联模型文件
// 创建一个模型对象
// 查找model文件的URL
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:modelName withExtension:@"momd"];
//控制台 po[NSBundle mainBundle]可以查看到实体model后缀的类型文件
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
// 持久化存储调度器
NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
// 存储数据库的名字
NSError *error = nil;
// 获取docment目录
NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
// 数据库保存的路径
NSString *sqlitePath = [doc stringByAppendingFormat:@"/%@.slqite",modelName];
[store addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:sqlitePath] options:nil error:&error];
context.persistentStoreCoordinator = store;
此时能够发现在沙盒目录下有两个数据库文件。
五、开打SQLITE开关
- 1.打开Product,点击EditScheme...
- 2.点击Arguments,在ArgumentsPassed On Launch中添加2项
- 1> -com.apple.CoreData.SQLDebug
- 2> 1
- 生成对应的sql的语句如控制台。
六:简单终结
•sqlite 和 CoreData 对比
sqlite 是纯c语言存储数据方式
coredata 也是对sqlite的封装 ,它数据的保存直接使用对象,不用再写sql语句
sqlite 性能优于 coredata
•什么时候使用sqlite 什么时候使用CoreData
"Coredata功能不是很强大
如果你的数据库表关联大复杂 三四张表都关联 -sqlite
如果数据表结构比较简单 就只有两三张,这些表没有关联关系 coreData