一、簡單介紹
Core Data是iOS5之后才出現(xiàn)的一個框架傲须,它提供了對象-關系映射(ORM)的功能蓝牲,即能夠將OC對象轉化成數(shù)據(jù),保存在SQLite數(shù)據(jù)庫文件中泰讽,也能夠將保存在數(shù)據(jù)庫中的數(shù)據(jù)還原成OC對象例衍。在此數(shù)據(jù)操作期間,我們不需要編寫任何SQL語句已卸。
對象-關系映射(ORM)
左邊是關系模型肄渗,即數(shù)據(jù)庫,數(shù)據(jù)庫里面有張person表咬最,person表里面有id翎嫡、name、age三個字段永乌,而且有2條記錄惑申;
右邊是對象模型,可以看到翅雏,有2個OC對象圈驼;
利用Core Data框架,我們就可以輕松地將數(shù)據(jù)庫里面的2條記錄轉換成2個OC對象望几,也可以輕松地將2個OC對象保存到數(shù)據(jù)庫中绩脆,變成2條表記錄,而且不用寫一條SQL語句橄抹。
二靴迫、創(chuàng)建模型
上文已經介紹過,CoreData可以將一個OC對象轉化成**關系模型 **(一個表格)存儲在SQLite中楼誓。那么玉锌,現(xiàn)在我們就需要創(chuàng)建一個存儲數(shù)據(jù)的Model類。具體操作如下:
1.創(chuàng)建后綴為.xcdatamodeld的模型文件
command+n:出現(xiàn)如下窗口疟羹,點擊next
彈出一個窗口主守,“Save as:”后面修改文件名禀倔,點擊Creat,出現(xiàn)如下界面:
點擊“Add Entity”添加實體参淫,出現(xiàn)綠色框中的“Entity”救湖,雙擊“Entity”,可以更改實體的名字涎才。比如鞋既,改為“People”。機智的騷年憔维,你是不是想到了什么涛救?是的,其實Entity就是一個NSObject业扒。既然如此检吆,我們就可以往這個叫做“Peolpe”的Entity中添加一些屬性。點擊Attributes下的“+”程储,如下圖:
有時由于項目需求蹭沛,需要在Entity(例如“People”)中添加另一個Entity(例如“Car”)作為它的屬性,而Car也有一個“People”屬性章鲤。那么摊灭,這兩個Entity是相互關聯(lián)的。我們需要給它們添加關聯(lián):
第一步:創(chuàng)建一個名為“Car”的Entity败徊。既然是添加關聯(lián)帚呼,我們當然要在Relationships下操作了。點擊Relationships下的“+”添加需要關聯(lián)的Entity( "People" )皱蹦∶荷保“Relationships”:自己定義(所要添加的屬性名); “Destination”:要關聯(lián)的Entity("People") ; “Inverse”:這個暫時不用管它(這個時候還無法操作)沪哺。
第二步:既然是相互關聯(lián)沈自,我們當然也要在People的Relationships下添加一個關聯(lián)。與第一步類似:“Relationships”:自己定義(所要添加的屬性名)辜妓; “Destination”:要關聯(lián)的Entity("Car") ; “Inverse”:點擊會有一個選擇框枯途,我這里的選項是“ower”,選擇它籍滴。
2.創(chuàng)建NSManagedObject子類
模型文件創(chuàng)建好后酪夷,接下來就要根據(jù)這個模型文件創(chuàng)建處相應的Model類,具體操作如下:點擊 .xcdatamodeld文件--->Editor--->Creat NSManagedObject Subclass
彈出一個窗口异逐,打上勾捶索,點擊Creat,又彈出一個窗口灰瞻,全鉤上腥例,Creat。最后酝润,生成八個文件燎竖,如下圖
三、數(shù)據(jù)操作
前文已經提過因為CoreData是蘋果公司封裝的數(shù)據(jù)持久化框架要销,所以CoreData數(shù)據(jù)持久化的操作构回,不需要編寫SQLite語句,而是要用到一些相關的類疏咐。比如:NSManagedObjectModel纤掸、NSPersistentStoreCoordinator、NSManagedObjectContext等等浑塞。
1.CoreData構成的類介紹
(1)NSManagedObjectContext: 被管理者對象上下文借跪, 相當于一個臨時數(shù)據(jù)庫, 我們存儲或者查詢都是通過這個對象來的酌壕;
(2)NSManagedObjectModel: 被管理對象模型掏愁,可以簡單的理解為可視化建模文件(.xcdatamodeld文件), 我們在可視化建模中是Entity自動生成model 方便讓文件存儲助理來進行管理卵牍;
(3)NSPersistentStoreCoordinator: 文件存儲助理果港,相當于數(shù)據(jù)庫的鏈接器,它是CoreData的核心 負責鏈接所有的模塊糊昙, 包括真實的存儲文件辛掠;
(4)NSManagedObject: 被管理的數(shù)據(jù)記錄,相當于數(shù)據(jù)庫中的表格記錄释牺;
(5)NSFetchRequest: 獲取數(shù)據(jù)的請求萝衩,相當于SQL語句;
(6)NSEntityDescription: 實體結構船侧,相當于表結構欠气;
2.CoreData核心類初始化
CoreData核心類就是NSManagedObjectModel、NSPersistentStoreCoordinator镜撩、NSManagedObjectContext预柒。CoreData的一系列操作都離不開這三個類,也正是因為它們這么重要袁梗,所以我們在創(chuàng)建工程時只要勾上CoreData選項宜鸯,Xcode就會在AppDelegate.m文件中自動生成這三個類的初始化代碼。
這些代碼你可以寫不出來遮怜,但是一定要清楚它們的作用淋袖,下面將對這些代碼做一些介紹注釋:
//獲取沙盒Document目錄路徑
- (NSURL*)applicationDocumentsDirectory {
return[[[NSFileManager defaultManager]URLsForDirectory:NSDocumentDirectoryinDomains:NSUserDomainMask]lastObject];
}
//被管理的對象模型
- (NSManagedObjectModel*)managedObjectModel {
if(_managedObjectModel!=nil) {
return_managedObjectModel;
}
//這里的@"*Model*"需要與.xcdatamodeld文件的名字一樣;.xcdatamodeld編譯后為.momd或.mom文件
NSURL*modelURL = [[NSBundle mainBundle]URLForResource:@"*Model*"withExtension:@"momd"];
_managedObjectModel= [[NSManagedObjectModel alloc]initWithContentsOfURL:modelURL];
return_managedObjectModel;
}
//持久化存儲助理:相當于數(shù)據(jù)庫的連接器
- (NSPersistentStoreCoordinator*)persistentStoreCoordinator {
if(_persistentStoreCoordinator!=nil) {
return_persistentStoreCoordinator;
}
_persistentStoreCoordinator= [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:[self managedObjectModel]];
//CoreData是建立在SQLite之上的锯梁,數(shù)據(jù)庫名稱需與.cdatamodel文件同名
NSURL*storeURL = [[self applicationDocumentsDirectory]URLByAppendingPathComponent:@"Model.sqlite"];
NSError*error =nil;
NSString*failureReason =@"There was an error creating or loading the application's saved data.";
if(! [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
NSMutableDictionary*dict = [NSMutableDictionary dictionary];
dict[NSLocalizedDescriptionKey] =@"Failed to initialize the application's saved data";
dict[NSLocalizedFailureReasonErrorKey] = failureReason;
dict[NSUnderlyingErrorKey] = error;
error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN"code:9999userInfo:dict];
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return_persistentStoreCoordinator;
}
//被管理的上下文:操作實際內容
- (NSManagedObjectContext*)managedObjectContext {
if(_managedObjectContext!=nil) {
return_managedObjectContext;
}
NSPersistentStoreCoordinator*coordinator = [self persistentStoreCoordinator];
if(!coordinator) {
return nil;
}
_managedObjectContext= [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return_managedObjectContext;
}
//保存數(shù)據(jù)
- (void)saveContext {
NSManagedObjectContext*managedObjectContext =self.managedObjectContext;
if(managedObjectContext !=nil) {
NSError*error =nil;
if([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
3.增即碗、刪焰情、改、查操作
以下操作均是利用Xcode自動在AppDelegate初始化CoreData的核心對象剥懒,所以首先需要初始化一個AppDelegate對象
AppDelegate*app=[[AppDelegate alloc]init];
插入數(shù)據(jù)
NSManagedObject*object=[NSEntityDescription insertNewObjectForEntityForName:entity inManagedObjectContext:app.managedObjectContext];
//第一種方式
[object setValue:@"Kevin" forKey:@"name"];
//第二種方式
(People*)people=object;
object.name=@"Kevin";
.......
//插入操作結束后記得保存
[app saveContext];
刪除數(shù)據(jù)
[app.managedObjectContext deleteObject:object];
[app saveContext];
查詢數(shù)據(jù)
//創(chuàng)建取回數(shù)據(jù)請求
NSFetchRequest*request=[[NSFetchRequest alloc]init];
//設置檢索的實體描述
NSEntityDescription*entityDes=[NSEntityDescription entityForName:@"People" inManagedObjectContext:app.managedObjectContext];
[request setEntity:entityDes];
//指定對檢索結果的排序方式(根據(jù)People的name屬性内舟,按升序排列)
NSSortDescriptor*sortDestor=[[NSSortDescriptor alloc]initWithKey:@"name" ascending:YES];
[request setSortDescriptors:@[sortDestor]];
//創(chuàng)建謂詞(搜索name=@"Kevin"的數(shù)據(jù))
NSPredicate*predicate=[NSPredicate predicateWithFormat:@"name=%@",@"Kevin"];
request.predicate=predicate;
NSError*error=nil;
//執(zhí)行請求,返回數(shù)組
NSArray*fetchedResult=[app.managedObjectContext executeFetchRequest:request error:&error];
修改數(shù)據(jù)
修改數(shù)據(jù)其實就是將查詢操作時返回的數(shù)組中的元素取出初橘,直接修改验游。(數(shù)組中的元素是指向內存地址的指針)
(People*)people=fetchedResult[0];
people.name=@"Tom";
項目開發(fā)過程中,在AppDelegate中初始化CoreData的核心對象并不是一種提倡的做法保檐。我們通常的做法是封裝一個CoreDataManager的單例類耕蝉。篇幅有限,這個將在下一章中介紹夜只。