ios開發(fā)常用的五種數(shù)據(jù)存儲(chǔ)方式:
- plist
- NSUserDefaults
- NSKeyedArchiver
- FMDB
- CoreData
這篇文章我們主要回顧Core Data
的使用
Core Data
因?yàn)镃ore data涉及到的東西較多,在這里先寫一些入門的操作(多表關(guān)聯(lián)以后會(huì)更新)
core data涉及到的一些類:
(1)NSManagedObjectContext(被管理的數(shù)據(jù)上下文)
操作實(shí)際內(nèi)容(操作持久層)
作用:插入數(shù)據(jù)鞋喇,查詢數(shù)據(jù)玷或,刪除數(shù)據(jù)
(2)NSManagedObjectModel(被管理的數(shù)據(jù)模型)
數(shù)據(jù)庫所有表格或數(shù)據(jù)結(jié)構(gòu)舆声,包含各實(shí)體的定義信息
作用:添加實(shí)體的屬性喊熟,建立屬性之間的關(guān)系
操作方法:視圖編輯器息裸,或代碼
(3)NSPersistentStoreCoordinator(持久化存儲(chǔ)助理)
相當(dāng)于數(shù)據(jù)庫的連接器
作用:設(shè)置數(shù)據(jù)存儲(chǔ)的名字疯兼,位置教馆,存儲(chǔ)方式,和存儲(chǔ)時(shí)機(jī)
(4)NSManagedObject(被管理的數(shù)據(jù)記錄)
相當(dāng)于數(shù)據(jù)庫中的表格記錄
(5)NSFetchRequest(獲取數(shù)據(jù)的請(qǐng)求)
相當(dāng)于查詢語句
(6)NSEntityDescription(實(shí)體結(jié)構(gòu))
相當(dāng)于表格結(jié)構(gòu),NSEntityDescription對(duì)象包含了Entity所擁有的屬性扒腕,關(guān)系等信息绢淀,我們可以通過NSEntityDescription生成相應(yīng)的NSManagedObject的實(shí)體
coredata的使用
1.創(chuàng)建coreDataDemo 如圖選中User Core Data
“Use Core Data”這個(gè)勾給我們做了些額外的工作,一是將“CoreData.framework”增加到我們工程的Frameworks列表中來了,二是在AppDelegate中增加了一些關(guān)于CoreData的代碼.
如果你的工程沒勾選“Use Core Data”這個(gè)選項(xiàng)瘾腰,你也可以模仿一個(gè)新創(chuàng)建的“Use Core Data”的工程把必要的代碼添加上去皆的,完全沒問題.
選中
2.添加實(shí)體
3.然后新建一個(gè)file,記得是NSManagedObject cubclass
生成四個(gè)文件(ios7之前是兩個(gè))
4.代碼示例
下面我們建立一個(gè)單例來演示coredate的 增蹋盆、刪费薄、改、查功能
(1) 增
//增
-(BOOL)saveCarInfoByCarModel:(CarModel *)carmodel
{
BOOL retVal = NO;
//NSManagedObjectContext(被管理的數(shù)據(jù)上下文),操作實(shí)際內(nèi)容(操作持久層)作用:插入數(shù)據(jù)栖雾,查詢數(shù)據(jù)楞抡,刪除數(shù)據(jù)
NSManagedObjectContext *context = [APPDELEGATE managedObjectContext];
//下面代碼相當(dāng)于 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中執(zhí)行
-(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(@"插入數(shù)據(jù)成功");
}
}
在此之前我們需要在appdelegate中打印數(shù)據(jù)庫的地址便于查看數(shù)據(jù)信息
運(yùn)行結(jié)果如下:
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] 插入數(shù)據(jù)成功
前往-->前往文件夾-->輸入數(shù)據(jù)庫地址后看到:
使用SQLiteManager打開數(shù)據(jù)庫文件
數(shù)據(jù)庫下載地址:https://github.com/skyxian/SQLiteManager
數(shù)據(jù)添加成功 !
然后我們?cè)俣嗵砑訋讉€(gè)數(shù)據(jù)便于改岩灭、刪拌倍、查的操作演示
我添加了六條數(shù)據(jù)如下:
(2) 刪
//刪:根據(jù)carID來刪除carID對(duì)應(yīng)的那個(gè)車輛
-(BOOL)deleteCarInfoByCarID:(NSString *)carID
{
BOOL retVal = NO;
NSManagedObjectContext *context = [APPDELEGATE managedObjectContext];
//建立請(qǐng)求
NSFetchRequest *request = [[NSFetchRequest alloc]init];
//讀取所有Car
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:context];
request.entity = entity;
//設(shè)置檢索條件(不設(shè)則默認(rèn)檢索所有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) {
//刪除對(duì)象
[context deleteObject:car];
}
//保存刪除的結(jié)果
if ([context save:nil]) {
retVal = YES;
}
}else{
NSLog(@"沒有檢索到對(duì)象");
}
return retVal;
}
VC中我們執(zhí)行 刪除carID = @"e28r22"的那個(gè)car對(duì)象的操作
-(void)deleteAction
{
CarModel *carmodel = [[CarModel alloc]init];
carmodel.carID = @"e28r22";
if ([[SingleTon sharedSingleTon] deleteCarInfoByCarID:carmodel.carID]) {
NSLog(@"刪除數(shù)據(jù)成功");
}
}
打印結(jié)果如下:
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] 刪除數(shù)據(jù)成功
我們打開數(shù)據(jù)庫查看
carID為@"e28r22"的那個(gè)car對(duì)象被我們成功刪除!
(3) 改
由上圖我們看到數(shù)據(jù)庫還有5條數(shù)據(jù)噪径,現(xiàn)在我們修改userid為2012 carid為r3nkr3 的數(shù)據(jù)信息(coredata中使用&&連接符)
//改:根據(jù)userID以及carID來修改車輛信息
-(BOOL)updateCarInfoByCarModel:(CarModel *)carmodel
{
BOOL retVal = NO;
NSManagedObjectContext *context = [APPDELEGATE managedObjectContext];
//建立請(qǐng)求
NSFetchRequest *request = [[NSFetchRequest alloc]init];
//讀取所有Car
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:context];
request.entity = entity;
//設(shè)置檢索條件(不設(shè)則默認(rèn)檢索所有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(@"沒有檢索到對(duì)象");
}
return retVal;
}
在VC中執(zhí)行
-(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(@"更新數(shù)據(jù)成功");
}
}
去數(shù)據(jù)庫查看
userid為2012 carid為r3nkr3 的數(shù)據(jù)被成功修改
(4) 查
我們來查找所有userid為2010的車輛信息
// 查:根據(jù)userID查尋該userID對(duì)應(yīng)的所有車輛
-(NSArray *)queryCarInfoByUserID:(NSString *)userID
{
NSManagedObjectContext *context = [APPDELEGATE managedObjectContext];
//建立請(qǐng)求
NSFetchRequest *request = [[NSFetchRequest alloc]init];
//讀取所有Car
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Car" inManagedObjectContext:context];
request.entity = entity;
//設(shè)置檢索條件(不設(shè)則默認(rèn)檢索所有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中執(zhí)行
-(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);
}
}
}
打印結(jié)果如下
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
查詢成功 !
數(shù)據(jù)遷移
假設(shè)存在這樣一個(gè)場(chǎng)景柱恤,car這個(gè)實(shí)體現(xiàn)有的屬性字段已經(jīng)無法滿足我們的需求,需要給它添加幾個(gè)字段并修改原有的部分字段找爱,這個(gè)時(shí)候我們就需要使用數(shù)據(jù)遷移了梗顺,否則程序會(huì)crash!
ok 车摄!我們?cè)诒綿emo中繼續(xù)演示 版本遷移
(1) 選中你的coreDataDemo.xcdatamodeld文件寺谤,選擇Xcode菜單editor->Add Model Version
比如取名:coreDataDemo 2.xcdatamodel
這個(gè)時(shí)候你會(huì)發(fā)現(xiàn)CoreData.xcdatamodeld中多了一個(gè)版本文件,如圖:
(2) 選擇剛才創(chuàng)建的版本吮播,在inspector中的Versioned Core Data Model選擇Current模版為coreDataDemo 2.xcdatamodel
(3) 修改新數(shù)據(jù)模型coreDataDemo 2变屁,在新的文件上添加屬性字段和修改實(shí)體 ( 切記!R夂荨粟关!是在新的coreDataDemo 2上添加及修改屬性)
(4) 修改原來的實(shí)體文件(或者刪除原來的實(shí)體文件,重新生成新的實(shí)體下的類)
(5)在AppDelegate.m的persistentStoreCoordinator中添加代碼:
運(yùn)行--成功 环戈!
現(xiàn)在我們?cè)俅蜗驍?shù)據(jù)庫中添加一條數(shù)據(jù)看看有什么效果
-(void)insertAction
{
/*
*
* 這里最好多添加幾條數(shù)據(jù)便于后面 刪闷板、改、查 的操作演示
*
*/
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(@"插入數(shù)據(jù)成功");
}
}
打印結(jié)果:
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] 插入數(shù)據(jù)成功
進(jìn)入數(shù)據(jù)庫查看
數(shù)據(jù)添加成功院塞,且數(shù)據(jù)庫中多了一個(gè)carDistance的字段遮晚,說明數(shù)據(jù)遷移成功!