ios开发常用的五种数据存储方式:
- plist
- NSUserDefaults
- NSKeyedArchiver
- FMDB
- CoreData
这篇文章我们主要回顾Core Data
的使用
Core Data
因为Core data涉及到的东西较多,在这里先写一些入门的操作(多表关联以后会更新)
core data涉及到的一些类:
(1)NSManagedObjectContext(被管理的数据上下文)
操作实际内容(操作持久层)
作用:插入数据,查询数据,删除数据
(2)NSManagedObjectModel(被管理的数据模型)
数据库所有表格或数据结构,包含各实体的定义信息
作用:添加实体的属性,建立属性之间的关系
操作方法:视图编辑器,或代码
(3)NSPersistentStoreCoordinator(持久化存储助理)
相当于数据库的连接器
作用:设置数据存储的名字,位置,存储方式,和存储时机
(4)NSManagedObject(被管理的数据记录)
相当于数据库中的表格记录
(5)NSFetchRequest(获取数据的请求)
相当于查询语句
(6)NSEntityDescription(实体结构)
相当于表格结构,NSEntityDescription对象包含了Entity所拥有的属性,关系等信息,我们可以通过NSEntityDescription生成相应的NSManagedObject的实体
coredata的使用
1.创建coreDataDemo 如图选中User Core Data
“Use Core Data”这个勾给我们做了些额外的工作,一是将“CoreData.framework”增加到我们工程的Frameworks列表中来了,二是在AppDelegate中增加了一些关于CoreData的代码.
如果你的工程没勾选“Use Core Data”这个选项,你也可以模仿一个新创建的“Use Core Data”的工程把必要的代码添加上去,完全没问题.
选中
2.添加实体
3.然后新建一个file,记得是NSManagedObject cubclass
生成四个文件(ios7之前是两个)
4.代码示例
下面我们建立一个单例来演示coredate的 增、删、改、查功能
(1) 增
//增
-(BOOL)saveCarInfoByCarModel:(CarModel *)carmodel
{
BOOL retVal = NO;
//NSManagedObjectContext(被管理的数据上下文),操作实际内容(操作持久层)作用:插入数据,查询数据,删除数据
NSManagedObjectContext *context = [APPDELEGATE managedObjectContext];
//下面代码相当于 alloc init 初始化
Car *car = [NSEntityDescription insertNewObjectForEntityForName:@"Car" inManagedObjectContext:context];
car.userID = carmodel.userID;
car.carID = carmodel.carID;
car.carName = carmodel.carName;
car.carNumber = carmodel.carNumber;
car.carIsDefault = carmodel.carIdDefault;
NSError *error;
if ([context save:&error]) {
NSLog(@"保存成功");
retVal = YES;
}
return retVal;
}
在VC中执行
-(void)insertAction
{
CarModel *carmodel = [[CarModel alloc]init];
carmodel.userID = @"2011";
carmodel.carID = @"1dwdwq";
carmodel.carName = @"兰博基尼";
carmodel.carNumber = @"京A93459";
carmodel.carIdDefault = @"0";
if ([[SingleTon sharedSingleTon] saveCarInfoByCarModel:carmodel]) {
NSLog(@"插入数据成功");
}
}
在此之前我们需要在appdelegate中打印数据库的地址便于查看数据信息
运行结果如下:
2016-11-30 12:51:29.163 coreDataDemo[31612:1990693] file:///Users/x8f/Library/Developer/CoreSimulator/Devices/7A1AE587-2880-40CE-A11B-17F7DFE94ACD/data/Containers/Data/Application/D66488E1-0E5E-44F8-B75A-5C44DD5954CF/Documents/coreDataDemo.sqlite
2016-11-30 12:51:29.174 coreDataDemo[31612:1990693] 保存成功
2016-11-30 12:51:29.174 coreDataDemo[31612:1990693] 插入数据成功
前往-->前往文件夹-->输入数据库地址后看到:
使用SQLiteManager打开数据库文件
数据库下载地址:https://github.com/skyxian/SQLiteManager
数据添加成功 !
然后我们再多添加几个数据便于改、删、查的操作演示
我添加了六条数据如下:
(2) 删
//删:根据carID来删除carID对应的那个车辆
-(BOOL)deleteCarInfoByCarID:(NSString *)carID
{
BOOL retVal = NO;
NSManagedObjectContext *context = [APPDELEGATE managedObjectContext];
//建立请求
NSFetchRequest *request = [[NSFetchRequest alloc]init];
//读取所有Car
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:context];
request.entity = entity;
//设置检索条件(不设则默认检索所有Car)
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"carID=%@",carID];
request.predicate = predicate;
NSError *error;
NSArray *arr = [context executeFetchRequest:request error:&error];
if (arr.count) {
for (Car *car in arr) {
//删除对象
[context deleteObject:car];
}
//保存删除的结果
if ([context save:nil]) {
retVal = YES;
}
}else{
NSLog(@"没有检索到对象");
}
return retVal;
}
VC中我们执行 删除carID = @"e28r22"的那个car对象的操作
-(void)deleteAction
{
CarModel *carmodel = [[CarModel alloc]init];
carmodel.carID = @"e28r22";
if ([[SingleTon sharedSingleTon] deleteCarInfoByCarID:carmodel.carID]) {
NSLog(@"删除数据成功");
}
}
打印结果如下:
2016-11-30 13:15:33.410 coreDataDemo[31862:2004730] file:///Users/x8f/Library/Developer/CoreSimulator/Devices/7A1AE587-2880-40CE-A11B-17F7DFE94ACD/data/Containers/Data/Application/6A977C79-3A51-449D-8D5E-EF5F8009D2EA/Documents/coreDataDemo.sqlite
2016-11-30 13:15:33.417 coreDataDemo[31862:2004730] 删除数据成功
我们打开数据库查看
carID为@"e28r22"的那个car对象被我们成功删除!
(3) 改
由上图我们看到数据库还有5条数据,现在我们修改userid为2012 carid为r3nkr3 的数据信息(coredata中使用&&连接符)
//改:根据userID以及carID来修改车辆信息
-(BOOL)updateCarInfoByCarModel:(CarModel *)carmodel
{
BOOL retVal = NO;
NSManagedObjectContext *context = [APPDELEGATE managedObjectContext];
//建立请求
NSFetchRequest *request = [[NSFetchRequest alloc]init];
//读取所有Car
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:context];
request.entity = entity;
//设置检索条件(不设则默认检索所有Car)
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"userID = %@ && carID = %@",carmodel.userID,carmodel.carID];
request.predicate = predicate;
NSError *error;
NSArray *arr = [context executeFetchRequest:request error:&error];
if (arr.count) {
for (Car *car in arr) {
car.userID = carmodel.userID;
car.carID = carmodel.carID;
car.carIsDefault = carmodel.carIdDefault;
car.carName = carmodel.carName;
car.carNumber = carmodel.carNumber;
if ([context save:nil]) {
retVal = YES;
}
}
}else{
NSLog(@"没有检索到对象");
}
return retVal;
}
在VC中执行
-(void)updateAction
{
CarModel *carmodel = [[CarModel alloc]init];
carmodel.userID = @"2012";
carmodel.carID = @"r3nkr3";
carmodel.carName = @"路虎";
carmodel.carNumber = @"京A80808";
carmodel.carIdDefault = @"1";
if ([[SingleTon sharedSingleTon] updateCarInfoByCarModel:carmodel]) {
NSLog(@"更新数据成功");
}
}
去数据库查看
userid为2012 carid为r3nkr3 的数据被成功修改
(4) 查
我们来查找所有userid为2010的车辆信息
// 查:根据userID查寻该userID对应的所有车辆
-(NSArray *)queryCarInfoByUserID:(NSString *)userID
{
NSManagedObjectContext *context = [APPDELEGATE managedObjectContext];
//建立请求
NSFetchRequest *request = [[NSFetchRequest alloc]init];
//读取所有Car
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:context];
request.entity = entity;
//设置检索条件(不设则默认检索所有Car)
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"userID = %@",userID];
request.predicate = predicate;
NSError *error;
NSMutableArray *listArr = [NSMutableArray new];
NSArray *arr = [context executeFetchRequest:request error:&error];
for (Car *car in arr) {
CarModel *model = [[CarModel alloc]init];
model.userID = car.userID;
model.carID = car.carID;
model.carIdDefault = car.carIsDefault;
model.carName = car.carName;
model.carNumber = car.carNumber;
[listArr addObject:model];
}
return listArr;
}
VC中执行
-(void)queryAction
{
CarModel *carmodel = [[CarModel alloc]init];
carmodel.userID = @"2010";
NSArray *arr = [[SingleTon sharedSingleTon]queryCarInfoByUserID:carmodel.userID];
if (arr) {
for (CarModel *model in arr) {
NSLog(@"%@---%@---%@---%@---%@",model.userID,model.carID,model.carName,model.carNumber,model.carIdDefault);
}
}
}
打印结果如下
2016-11-30 13:35:24.914 coreDataDemo[31986:2016010] file:///Users/x8f/Library/Developer/CoreSimulator/Devices/7A1AE587-2880-40CE-A11B-17F7DFE94ACD/data/Containers/Data/Application/99FCBB9B-41BD-460F-BF23-7231126FDFC4/Documents/coreDataDemo.sqlite
2016-11-30 13:35:24.919 coreDataDemo[31986:2016010] 2010---29eh4f---法拉利---京A429e8---1
2016-11-30 13:35:24.919 coreDataDemo[31986:2016010] 2010---bi3k1---大众---京A82eb2---0
2016-11-30 13:35:24.919 coreDataDemo[31986:2016010] 2010---9d20d2---蒙迪欧---京A11111---0
查询成功 !
数据迁移
假设存在这样一个场景,car这个实体现有的属性字段已经无法满足我们的需求,需要给它添加几个字段并修改原有的部分字段,这个时候我们就需要使用数据迁移了,否则程序会crash!
ok !我们在本demo中继续演示 版本迁移
(1) 选中你的coreDataDemo.xcdatamodeld文件,选择Xcode菜单editor->Add Model Version
比如取名:coreDataDemo 2.xcdatamodel
这个时候你会发现CoreData.xcdatamodeld中多了一个版本文件,如图:
(2) 选择刚才创建的版本,在inspector中的Versioned Core Data Model选择Current模版为coreDataDemo 2.xcdatamodel
(3) 修改新数据模型coreDataDemo 2,在新的文件上添加属性字段和修改实体 ( 切记!!!是在新的coreDataDemo 2上添加及修改属性)
(4) 修改原来的实体文件(或者删除原来的实体文件,重新生成新的实体下的类)
(5)在AppDelegate.m的persistentStoreCoordinator中添加代码:
运行--成功 !
现在我们再次向数据库中添加一条数据看看有什么效果
-(void)insertAction
{
/*
*
* 这里最好多添加几条数据便于后面 删、改、查 的操作演示
*
*/
CarModel *carmodel = [[CarModel alloc]init];
carmodel.userID = @"2013";
carmodel.carID = @"8f3hf3";
carmodel.carName = @"法拉利";
carmodel.carNumber = @"京A86868";
carmodel.carIdDefault = @"0";
if ([[SingleTon sharedSingleTon] saveCarInfoByCarModel:carmodel]) {
NSLog(@"插入数据成功");
}
}
打印结果:
2016-11-30 15:02:35.063 coreDataDemo[32513:2055137] file:///Users/x8f/Library/Developer/CoreSimulator/Devices/7A1AE587-2880-40CE-A11B-17F7DFE94ACD/data/Containers/Data/Application/EF713FA9-E1D0-4E42-BC6A-CBBF438AB4A9/Documents/coreDataDemo.sqlite
2016-11-30 15:02:35.136 coreDataDemo[32513:2055137] 保存成功
2016-11-30 15:02:35.136 coreDataDemo[32513:2055137] 插入数据成功
进入数据库查看
数据添加成功,且数据库中多了一个carDistance的字段,说明数据迁移成功!