數(shù)據(jù)存儲(chǔ)之CoreData(基礎(chǔ))

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


90FF46FE-6465-49C2-9FD7-3CDAA95D6855.png

“Use Core Data”這個(gè)勾給我們做了些額外的工作,一是將“CoreData.framework”增加到我們工程的Frameworks列表中來了,二是在AppDelegate中增加了一些關(guān)于CoreData的代碼.
如果你的工程沒勾選“Use Core Data”這個(gè)選項(xiàng)瘾腰,你也可以模仿一個(gè)新創(chuàng)建的“Use Core Data”的工程把必要的代碼添加上去皆的,完全沒問題.
選中


屏幕快照 2016-11-29 下午8.57.28.png

2.添加實(shí)體
53464188-A7E9-46C4-B46D-2FBF96C0C8B9.png

3.然后新建一個(gè)file,記得是NSManagedObject cubclass

5556A2E1-D835-4007-AC99-72A6CD50DF3F.png
0E3675FA-EC3C-47A5-8391-9B9C5E01D3D9.png
BA7400A0-AEFB-4114-9726-FC643F3121B1.png

生成四個(gè)文件(ios7之前是兩個(gè))

屏幕快照 2016-11-30 下午12.40.07.png

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ù)信息

F65A0799-062D-4FBF-80A1-3835F27AA2C1.png

運(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ù)庫地址后看到:

屏幕快照 2016-11-30 下午12.53.26.png

使用SQLiteManager打開數(shù)據(jù)庫文件
數(shù)據(jù)庫下載地址:https://github.com/skyxian/SQLiteManager
屏幕快照 2016-11-30 下午12.53.50.png

屏幕快照 2016-11-30 下午12.54.12.png

數(shù)據(jù)添加成功 !
然后我們?cè)俣嗵砑訋讉€(gè)數(shù)據(jù)便于改岩灭、刪拌倍、查的操作演示
我添加了六條數(shù)據(jù)如下:

1.02.33.png

(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ù)庫查看

1.18.15.png

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ù)庫查看

BCB302D6-83F6-4410-9DAC-5DA5EA91D8A1.png

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

屏幕快照 2016-11-30 下午2.25.21.png
1628981F-4EEC-4084-BBCE-56FEC8D70CE9.png

這個(gè)時(shí)候你會(huì)發(fā)現(xiàn)CoreData.xcdatamodeld中多了一個(gè)版本文件,如圖:

屏幕快照 2016-11-30 下午2.39.05.png

(2) 選擇剛才創(chuàng)建的版本吮播,在inspector中的Versioned Core Data Model選擇Current模版為coreDataDemo 2.xcdatamodel


451AC5F8-650F-4D14-9971-8B88CE127F9D.png

(3) 修改新數(shù)據(jù)模型coreDataDemo 2变屁,在新的文件上添加屬性字段和修改實(shí)體 ( 切記!R夂荨粟关!是在新的coreDataDemo 2上添加及修改屬性)

9326245E-F836-4E78-AAEB-5C1376ABBFBC.png

(4) 修改原來的實(shí)體文件(或者刪除原來的實(shí)體文件,重新生成新的實(shí)體下的類)

C38126DA-403D-4EC3-A6C1-F3F69D00DE20.png
1CF7413C-187E-431B-BC84-AD22EFC67730.png

(5)在AppDelegate.m的persistentStoreCoordinator中添加代碼:

758E84FB-E3E8-4DBC-A74C-EFB22D63EFC9.png

運(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ù)庫查看

05AA1904-6652-4518-8DB1-32DE310443CD.png

數(shù)據(jù)添加成功院塞,且數(shù)據(jù)庫中多了一個(gè)carDistance的字段遮晚,說明數(shù)據(jù)遷移成功!

demo地址:https://github.com/skyxian/coreDataDemo
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拦止,一起剝皮案震驚了整個(gè)濱河市县遣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖萧求,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件括蝠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡饭聚,警方通過查閱死者的電腦和手機(jī)忌警,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秒梳,“玉大人法绵,你說我怎么就攤上這事±业猓” “怎么了朋譬?”我有些...
    開封第一講書人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)兴垦。 經(jīng)常有香客問我徙赢,道長(zhǎng),這世上最難降的妖魔是什么探越? 我笑而不...
    開封第一講書人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任狡赐,我火速辦了婚禮,結(jié)果婚禮上钦幔,老公的妹妹穿的比我還像新娘枕屉。我一直安慰自己,他們只是感情好鲤氢,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開白布搀擂。 她就那樣靜靜地躺著,像睡著了一般卷玉。 火紅的嫁衣襯著肌膚如雪哨颂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評(píng)論 1 291
  • 那天相种,我揣著相機(jī)與錄音威恼,去河邊找鬼。 笑死蚂子,一個(gè)胖子當(dāng)著我的面吹牛沃测,可吹牛的內(nèi)容都是我干的缭黔。 我是一名探鬼主播食茎,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼馏谨!你這毒婦竟也來了别渔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎哎媚,沒想到半個(gè)月后喇伯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拨与,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年稻据,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片买喧。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡捻悯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出淤毛,到底是詐尸還是另有隱情今缚,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布低淡,位于F島的核電站姓言,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蔗蹋。R本人自食惡果不足惜何荚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望猪杭。 院中可真熱鬧兽泣,春花似錦、人聲如沸胁孙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涮较。三九已至稠鼻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間狂票,已是汗流浹背候齿。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留闺属,地道東北人慌盯。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像掂器,于是被迫代替她去往敵國(guó)和親亚皂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容