简单说明
coreData是苹果提供的数据本地化的解决方案中的一种,实质还是提供数据库去存储数据,只是在coreData中不需要程序员手动创建数据库文件,由coreData自动创建。 coreData的核心文件和类 1.模型文件:后缀是.xcdatamodeld
的文件,相当于数据库文件(数据库文件代言人) 2.实体:相当于表 3.实体类:存储对象对应的类 4.上下文:关联模型文件和实际生成的数据库文件(对上下文的操作就相当于对数据库进行操作) 使用步骤 1.创建模型文件(已经自动创建完成,但是要在创建工程的时候勾选coreData的选项)
1.获取上下文
既然上面说到上下文是关联模型文件和实际生成的数据库文件,对上下文的操作就相当于是对数据库进行操作,那么这里的上下文就相当于是一个数据库操作者,那么我们就要获取到这个上下文。 首先先声明一个上下文
// 声明上下文
NSManagedObjectContext *_context;
复制代码
// 1.获取上下文(相当于打开数据库)
// 拿到应用程序的delegate
AppDelegate *delegate = [UIApplication sharedApplication].delegate;
_context = delegate.managedObjectContext;
复制代码
coreData还是对数据的操作,那就一定离不开数据的增删改查。
2.增加数据
1.插入单条数据
// 1.创建需要插入的对象(可以像alloc出来的对象一样的使用,只是多了一些功能)
/**
* @param NSString 实体名(相当于表名)
* @return 上下文(相当于数据库)
*/
Student *stu = [NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:_context];
复制代码
// 2.给对象的属性进行赋值
stu.name = @"wj";
stu.age = @25;
stu.sex = @"未知";
复制代码
// 3.保存数据库
// 参数:错误信息
// 返回值:执行结果
BOOL ret = [_context save:nil];
if (ret) {
NSLog(@"保存成功");
}
else {
NSLog(@"保存失败");
}
复制代码
这样就把一条数据插入到数据库中去了,打印下沙盒路径也可以去查找到数据的存在。 2.插入多条数据 插入多条数据可以使用一个for循环进行插入,简单粗暴。
for (int i = 0; i < 10; ++i) {
// 1.创建对象
Student *stu2 = [NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:_context];
// 2.给属性赋值
stu2.name = [NSString stringWithFormat:@"name%d",i];
stu2.age = [NSNumber numberWithInteger:(arc4random() % 15 + 15)];
stu2.sex = arc4random() % 2 == 0 ? @"男" : @"女";
// 放到循环里的,执行的时候就一条一条的存入到数据库中
//[_context save:nil];
}
// 3.保存数据库
// 同时插入多条的数据时时运用的多线程,同时执行
[_context save:nil];
复制代码
从上面可以知道,数据的插入的会用到的方法为+ (__kindof NSManagedObject *)insertNewObjectForEntityForName:(NSString *)entityName inManagedObjectContext:(NSManagedObjectContext *)context;
。 所以对数据插入后调用的方法为:- (BOOL)save:(NSError **)error;
,表示对数据库进行保存操作。
3.查询数据
1.创建查询对象
// 1.创建查询对象
// 参数:实体(相当于表名)
NSFetchRequest *fetch_t = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
复制代码
这个name要和创建实体的名字一致。 2.直接查询
// 1.直接查询(将表中所有的数据全部获取到)
// 返回值:查询结果
NSArray *array = [_context executeFetchRequest:fetch_t error:nil];
// 遍历获取所有的对象
for (Student *stu in array) {
[stu show];
}
复制代码
3.按条件进行查询 按条件进行查询可以使用谓词
进行查询,谓词
相当于就是一个查询的条件而已。
// 1.创建条件对象
// 参数:查询条件
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age < 18"];
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"age = 18 and sex = '男'"];
// 条件:age的值不固定
NSPredicate *predicate3 = [NSPredicate predicateWithFormat:@"age < %d",25];
// 条件:值和属性都不固定(属性不固定,用K占位)
NSPredicate *predicate4 = [NSPredicate predicateWithFormat:@"%K < %d", @"age", 30];
// 2.给查询对象添加条件
[fetch_t setPredicate:predicate4];
// 3.查询结果
NSArray *result = [_context executeFetchRequest:fetch_t error:nil];
// 遍历获取的所有对象
for (Student *stu2 in result) {
[stu2 show];
}
复制代码
4.查询结果排序
// 1.创建一个排序对象
// 参数1:排序的条件(按属性进行排序)
// 参数2:是否升序
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
//2.设置查询对象的排序属性
fetch_t.sortDescriptors = @[sort];
// 3.查询结果
NSArray *sortAscend = [_context executeFetchRequest:fetch_t error:nil];
for (Student *stu4 in sortAscend) {
[stu4 show];
}
复制代码
到这里后上下文会引用一个方法就是- (nullable NSArray *)executeFetchRequest:(NSFetchRequest *)request error:(NSError **)error;
进行查询。 查询结果的显示是在Student
这个类写了一个方法而已,
- (void)show {
NSLog(@"%@ ~ %@ ~ %@",self.name, self.age, self.sex);
}
复制代码
4.删除数据
想要删除数据,那么首先要得找到这条数据,所以我们要的使用查询数据库的手段,所以我们就得按照条件进行查询数据。 1.数据的查询
// 1.按条件将需要删除的数据查询出来
NSFetchRequest *fetch_t = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
NSPredicate *pre = [NSPredicate predicateWithFormat:@"age < 25"];
fetch_t.predicate = pre;
NSArray *array = [_context executeFetchRequest:fetch_t error:nil];
复制代码
2.删除数据 按条件找到相应的数据了,就可以进行删除了。
// 2.遍历查询结果,将结果中的对象删除
for (Student *stu in array) {
// 我觉得这个地方应该在判断下array到底有没有值,没有就直接返回,有值才去删除操作
[_context deleteObject:stu];
}
复制代码
上面得到删除数据的方法为:- (void)deleteObject:(NSManagedObject *)object;
。
5.更新数据
其实说到底更新数据和删除数据没有多大的差别,在实现上来说,都需要按条件找到相应的数据,只是删除的话是把数据删除了,而更新是要把数据附上一个新的值而已,最后将数据库进行保存。
// 1.按条件将需要删除的数据查询出来
NSFetchRequest *fetch_t = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
NSPredicate *pre = [NSPredicate predicateWithFormat:@"age < 25"];
fetch_t.predicate = pre;
NSArray *array = [_context executeFetchRequest:fetch_t error:nil];
// 2.遍历查询结果,将结果中的对象更新
for (Student *stu in array) {
stu.age = @20;
}
// 3.保存数据库
[_context save:nil];
复制代码
coreData和sqlite3的比较
1.sqlite3是通过sql语句直接操作对象的属性;而coreData是直接对对象进行操作的。而两者都是直接或者间接对数据库文件进行操作的。 2.sqlite3使用的时候更加灵活,但是需要sql语句,这不能有一点的写错了,再加上Xcode对sql语句没有语法提示的。coreData不用sql语句编写就可以操作数据库的,但是对数据库的操作还是不够灵活(在runtime是不能使用coreData的,只能使用sqlite3或者是FMDB进行操作的)。 3.如果整个工程的数据结构比较简单的时候,尽量的去使用coreData进行数据本地化的处理。