CoreData

簡介

  Core Data是iOS5之後纔出現的一個框架,它提供了對象-關係映射(ORM)的功能,即能夠將OC對象轉化成數據,保存在SQLite數據庫文件中,也能夠將保存在數據庫中的數據還原成OC對象。在此數據操作期間,我們不需要編寫任何SQL語句,這個有點類似於著名的Hibernate持久化框架,不過功能肯定是沒有Hibernate強大的。簡單地用下圖描述下它的作用:

abc

左邊是關係模型,即數據庫,數據庫裏面有張person表,person表裏面有id、name、age三個字段,而且有2條記錄;

右邊是對象模型,可以看到,有2個OC對象;

利用Core Data框架,我們就可以輕鬆地將數據庫裏面的2條記錄轉換成2個OC對象,也可以輕鬆地將2個OC對象保存到數據庫中,變成2條表記錄,而且不用寫一條SQL語句。


模型文件

  在Core Data,需要進行映射的對象稱爲實體(entity),而且需要使用Core Data的模型文件來描述app中的所有實體和實體屬性。這裏以Person(人)和Card(身份證)2個實體爲例子,先看看實體屬性和實體之間的關聯關係
abc
Person實體中有:name(姓名)、age(年齡)、card(身份證)三個屬性
Card實體中有:no(號碼)、person(人)兩個屬性

接下來看看創建模型文件的過程:
1.選擇模板
abcabc

2.添加實體


3.添加Person的2個基本屬性



4.添加Card的1個基本屬性



5.建立Card和Person的關聯關係

        

右圖中的表示Card中有個Person類型的person屬性,目的就是建立Card跟Person之間的一對一關聯關係(建議補上這一項),在Person中加上Inverse屬性後,你會發現Card中Inverse屬性也自動補上了



瞭解NSManagedObject

1.通過Core Data從數據庫取出的對象,默認情況下都是NSManagedObject對象
 

2.NSManagedObject的工作模式有點類似於NSDictionary對象,通過鍵-值對來存取所有的實體屬性

1> setValue:forKey:存儲屬性值(屬性名爲key)

2> valueForKey:獲取屬性值(屬性名爲key)


CoreData中的核心對象



注:黑色表示類名,紅色表示類裏面的一個屬性
發步驟總結:
1.初始化NSManagedObjectModel對象,加載模型文件,讀取app中的所有實體信息
2.初始化NSPersistentStoreCoordinator對象,添加持久化庫(這裏採取SQLite數據庫)
3.初始化NSManagedObjectContext對象,拿到這個上下文對象操作實體,進行CRUD操


代碼實現

添加CoreData.framework和導入主頭文件<CoreData/CoreData.h>


1.搭建上下文環境
  1. // 從應用程序包中加載模型文件  
  2. NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];  
  3. // 傳入模型對象,初始化NSPersistentStoreCoordinator  
  4. NSPersistentStoreCoordinator *psc = [[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model] autorelease];  
  5. // 構建SQLite數據庫文件的路徑  
  6. NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];  
  7. NSURL *url = [NSURL fileURLWithPath:[docs stringByAppendingPathComponent:@"person.data"]];  
  8. // 添加持久化存儲庫,這裏使用SQLite作爲存儲庫  
  9. NSError *error = nil;  
  10. NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error];  
  11. if (store == nil) { // 直接拋異常  
  12.     [NSException raise:@"添加數據庫錯誤" format:@"%@", [error localizedDescription]];  
  13. }  
  14. // 初始化上下文,設置persistentStoreCoordinator屬性  
  15. NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];  
  16. context.persistentStoreCoordinator = psc;  
  17. // 用完之後,記得要[context release];  

2.添加數據到數據庫
  1. // 傳入上下文,創建一個Person實體對象  
  2. NSManagedObject *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];  
  3. // 設置Person的簡單屬性  
  4. [person setValue:@"MJ" forKey:@"name"];  
  5. [person setValue:[NSNumber numberWithInt:27] forKey:@"age"];  
  6. // 傳入上下文,創建一個Card實體對象  
  7. NSManagedObject *card = [NSEntityDescription insertNewObjectForEntityForName:@"Card" inManagedObjectContext:context];  
  8. [card setValue:@"4414241933432" forKey:@"no"];  
  9. // 設置Person和Card之間的關聯關係  
  10. [person setValue:card forKey:@"card"];  
  11. // 利用上下文對象,將數據同步到持久化存儲庫  
  12. NSError *error = nil;  
  13. BOOL success = [context save:&error];  
  14. if (!success) {  
  15.     [NSException raise:@"訪問數據庫錯誤" format:@"%@", [error localizedDescription]];  
  16. }  
  17. // 如果是想做更新操作:只要在更改了實體對象的屬性後調用[context save:&error],就能將更改的數據同步到數據庫  

3.從數據庫中查詢數據
  1. // 初始化一個查詢請求  
  2. NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];  
  3. // 設置要查詢的實體  
  4. request.entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context];  
  5. // 設置排序(按照age降序)  
  6. NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:NO];  
  7. request.sortDescriptors = [NSArray arrayWithObject:sort];  
  8. // 設置條件過濾(搜索name中包含字符串"Itcast-1"的記錄,注意:設置條件過濾時,數據庫SQL語句中的%要用*來代替,所以%Itcast-1%應該寫成*Itcast-1*)  
  9. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@", @"*Itcast-1*"];  
  10. request.predicate = predicate;  
  11. // 執行請求  
  12. NSError *error = nil;  
  13. NSArray *objs = [context executeFetchRequest:request error:&error];  
  14. if (error) {  
  15.     [NSException raise:@"查詢錯誤" format:@"%@", [error localizedDescription]];  
  16. }  
  17. // 遍歷數據  
  18. for (NSManagedObject *obj in objs) {  
  19.     NSLog(@"name=%@", [obj valueForKey:@"name"]  
  20. }  
注:Core Data不會根據實體中的關聯關係立即獲取相應的關聯對象,比如通過Core Data取出Person實體時,並不會立即查詢相關聯的Card實體;當應用真的需要使用Card時,纔會再次查詢數據庫,加載Card實體的信息。這個就是Core Data的延遲加載機制

4.刪除數據庫中的數據

  1. // 傳入需要刪除的實體對象  
  2. [context deleteObject:managedObject];  
  3. // 將結果同步到數據庫  
  4. NSError *error = nil;  
  5. [context save:&error];  
  6. if (error) {  
  7.     [NSException raise:@"刪除錯誤" format:@"%@", [error localizedDescription]];  
  8. }  

打開CoreData的SQL語句輸出開關

1.打開Product,點擊EditScheme...
2.點擊Arguments,在ArgumentsPassed On Launch中添加2項
1> -com.apple.CoreData.SQLDebug
2> 1




創建NSManagedObject的子類

默認情況下,利用Core Data取出的實體都是NSManagedObject類型的,能夠利用鍵-值對來存取數據。但是一般情況下,實體在存取數據的基礎上,有時還需要添加一些業務方法來完成一些其他任務,那麼就必須創建NSManagedObject的子類


選擇模型文件


選擇需要創建子類的實體


創建完畢後,多了2個子類


文件內容展示:
Person.h
  1. #import <Foundation/Foundation.h>  
  2. #import <CoreData/CoreData.h>  
  3.   
  4. @class Card;  
  5.   
  6. @interface Person : NSManagedObject  
  7.   
  8. @property (nonatomic, retain) NSString * name;  
  9. @property (nonatomic, retain) NSNumber * age;  
  10. @property (nonatomic, retain) Card *card;  
  11.   
  12. @end  

Person.m
  1. #import "Person.h"  
  2.   
  3. @implementation Person  
  4.   
  5. @dynamic name;  
  6. @dynamic age;  
  7. @dynamic card;  
  8.   
  9. @end  

Card.h
  1. #import <Foundation/Foundation.h>  
  2. #import <CoreData/CoreData.h>  
  3.   
  4. @class Person;  
  5.   
  6. @interface Card : NSManagedObject  
  7.   
  8. @property (nonatomic, retain) NSString * no;  
  9. @property (nonatomic, retain) Person *person;  
  10.   
  11. @end  

Card.m
  1. #import "Card.h"  
  2. #import "Person.h"  
  3.   
  4. @implementation Card  
  5.   
  6. @dynamic no;  
  7. @dynamic person;  
  8.   
  9. @end  

那麼往數據庫中添加數據的時候就應該寫了:
  1. Person *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];  
  2. person.name = @"MJ";  
  3. person.age = [NSNumber numberWithInt:27];  
  4.   
  5. Card *card = [NSEntityDescription insertNewObjectForEntityForName:@”Card" inManagedObjectContext:context];  
  6. card.no = @”4414245465656";  
  7. person.card = card;  
  8. // 最後調用[context save&error];保存數據  


說到這裏,整個Core Data框架的入門就結束了,其實Core Data還遠不止這些功能,它還支持自動撤銷機制,一對多關聯等,這裏就不一一介紹了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章