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

ios開發(fā)常用的五種數(shù)據(jù)存儲方式:

  • plist
  • NSUserDefaults
  • NSKeyedArchiver
  • FMDB
  • CoreData

這篇文章我們主要回顧Core Data的使用

Core Data

因?yàn)镃ore data涉及到的東西較多,在這里先寫一些入門的操作(多表關(guān)聯(lián)以后會更新)
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(持久化存儲助理)
    相當(dāng)于數(shù)據(jù)庫的連接器
    作用:設(shè)置數(shù)據(jù)存儲的名字,位置,存儲方式,和存儲時(shí)機(jī)
 (4)NSManagedObject(被管理的數(shù)據(jù)記錄)
    相當(dāng)于數(shù)據(jù)庫中的表格記錄
 (5)NSFetchRequest(獲取數(shù)據(jù)的請求)
    相當(dāng)于查詢語句
 (6)NSEntityDescription(實(shí)體結(jié)構(gòu))
    相當(dāng)于表格結(jié)構(gòu),NSEntityDescription對象包含了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ù)添加成功 !
然后我們再多添加幾個(gè)數(shù)據(jù)便于改、刪、查的操作演示
我添加了六條數(shù)據(jù)如下:

1.02.33.png

(2) 刪

//刪:根據(jù)carID來刪除carID對應(yīng)的那個(gè)車輛
-(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;
   //設(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) {
           //刪除對象
           [context deleteObject:car];
       }
       //保存刪除的結(jié)果
       if ([context save:nil]) {
           retVal = YES;
       }
   }else{
       NSLog(@"沒有檢索到對象");
   }
   return retVal;
}


VC中我們執(zhí)行 刪除carID = @"e28r22"的那個(gè)car對象的操作

-(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對象被我們成功刪除!

(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];
    //建立請求
    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(@"沒有檢索到對象");
      }
    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對應(yīng)的所有車輛
-(NSArray *)queryCarInfoByUserID:(NSString *)userID
{
   NSManagedObjectContext *context = [APPDELEGATE managedObjectContext];
   //建立請求
   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è)場景,car這個(gè)實(shí)體現(xiàn)有的屬性字段已經(jīng)無法滿足我們的需求,需要給它添加幾個(gè)字段并修改原有的部分字段,這個(gè)時(shí)候我們就需要使用數(shù)據(jù)遷移了,否則程序會crash!
ok !我們在本demo中繼續(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í)候你會發(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í)體 ( 切記!!!是在新的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)在我們再次向數(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)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評論 6 541
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,471評論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,436評論 2 378

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