Core Data是iOS5以後纔出現的一個框架,它提供了對象-關係映射(ORM)的功能,即可以將OC對象轉化成數據,保存在SQLite數據庫文件中,也可以將保存在數據庫中的數據還原成OC對象。在此數據操做期間,咱們不須要編寫任何SQL語句,這個有點相似於著名的Hibernate持久化框架,不過功能確定是沒有Hibernate強大的。簡單地用下圖描述下它的做用: java
左邊是關係模型,即數據庫,數據庫裏面有張person表,person表裏面有id、name、age三個字段,並且有2條記錄; 數據庫
右邊是對象模型,能夠看到,有2個OC對象; app
利用Core Data框架,咱們就能夠輕鬆地將數據庫裏面的2條記錄轉換成2個OC對象,也能夠輕鬆地將2個OC對象保存到數據庫中,變成2條表記錄,並且不用寫一條SQL語句。 框架
模型文件
在
Core Data
,須要進行映射的對象稱爲
實體
(entity)
,並且須要使用
Core Data
的模型文件來描述app中的全部實體和實體屬性。這裏以Person(人)和Card(身份證)2個實體爲例子,先看看實體屬性和實體之間的關聯關係:

Person實體中有:name(姓名)、age(年齡)、card(身份證)三個屬性
Card實體中有:no(號碼)、person(人)兩個屬性
接下來看看建立模型文件的過程:
1.選擇模板


2.添加實體

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

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

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

瞭解NSManagedObject
1.經過
Core Data
從數據庫取出的對象,默認狀況下都是
NSManagedObject
對象

2.
NSManagedObject
的工做模式有點相似於
NSDictionary
對象,經過鍵
-
值對來存取全部的實體屬性
1> setValue:forKey:存儲屬性值(屬性名爲key) url
2>
valueForKey:
獲取屬性值
(
屬性名爲
key)
CoreData中的核心對象
注:黑色表示類名,紅色表示類裏面的一個屬性
開
發步驟總結:
1.初始化NSManagedObjectModel對象,加載模型文件,讀取app中的全部實體信息
2.初始化NSPersistentStoreCoordinator對象,添加持久化庫(這裏採起SQLite數據庫)
3.初始化NSManagedObjectContext對象,拿到這個上下文對象操做實體,進行CRUD操做
代碼實現
先
添加CoreData.framework和導入主頭文件<CoreData/CoreData.h>
1.搭建上下文環境
- // 從應用程序包中加載模型文件
- NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
- // 傳入模型對象,初始化NSPersistentStoreCoordinator
- NSPersistentStoreCoordinator *psc = [[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model] autorelease];
- // 構建SQLite數據庫文件的路徑
- NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
- NSURL *url = [NSURL fileURLWithPath:[docs stringByAppendingPathComponent:@"person.data"]];
- // 添加持久化存儲庫,這裏使用SQLite做爲存儲庫
- NSError *error = nil;
- NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error];
- if (store == nil) { // 直接拋異常
- [NSException raise:@"添加數據庫錯誤" format:@"%@", [error localizedDescription]];
- }
- // 初始化上下文,設置persistentStoreCoordinator屬性
- NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
- context.persistentStoreCoordinator = psc;
- // 用完以後,記得要[context release];
2.添加數據到數據庫
- // 傳入上下文,建立一個Person實體對象
- NSManagedObject *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];
- // 設置Person的簡單屬性
- [person setValue:@"MJ" forKey:@"name"];
- [person setValue:[NSNumber numberWithInt:27] forKey:@"age"];
- // 傳入上下文,建立一個Card實體對象
- NSManagedObject *card = [NSEntityDescription insertNewObjectForEntityForName:@"Card" inManagedObjectContext:context];
- [card setValue:@"4414241933432" forKey:@"no"];
- // 設置Person和Card之間的關聯關係
- [person setValue:card forKey:@"card"];
- // 利用上下文對象,將數據同步到持久化存儲庫
- NSError *error = nil;
- BOOL success = [context save:&error];
- if (!success) {
- [NSException raise:@"訪問數據庫錯誤" format:@"%@", [error localizedDescription]];
- }
- // 若是是想作更新操做:只要在更改了實體對象的屬性後調用[context save:&error],就能將更改的數據同步到數據庫
3.從數據庫中查詢數據
- // 初始化一個查詢請求
- NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
- // 設置要查詢的實體
- request.entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context];
- // 設置排序(按照age降序)
- NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:NO];
- request.sortDescriptors = [NSArray arrayWithObject:sort];
- // 設置條件過濾(搜索name中包含字符串"Itcast-1"的記錄,注意:設置條件過濾時,數據庫SQL語句中的%要用*來代替,因此%Itcast-1%應該寫成*Itcast-1*)
- NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@", @"*Itcast-1*"];
- request.predicate = predicate;
- // 執行請求
- NSError *error = nil;
- NSArray *objs = [context executeFetchRequest:request error:&error];
- if (error) {
- [NSException raise:@"查詢錯誤" format:@"%@", [error localizedDescription]];
- }
- // 遍歷數據
- for (NSManagedObject *obj in objs) {
- NSLog(@"name=%@", [obj valueForKey:@"name"]
- }
注:Core Data不會根據實體中的關聯關係當即獲取相應的關聯對象,好比經過Core Data取出Person實體時,並不會當即查詢相關聯的Card實體;當應用真的須要使用Card時,纔會再次查詢數據庫,加載Card實體的信息。這個就是Core Data的延遲加載機制
4.刪除數據庫中的數據
- // 傳入須要刪除的實體對象
- [context deleteObject:managedObject];
- // 將結果同步到數據庫
- NSError *error = nil;
- [context save:&error];
- if (error) {
- [NSException raise:@"刪除錯誤" format:@"%@", [error localizedDescription]];
- }
打開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
- #import <Foundation/Foundation.h>
- #import <CoreData/CoreData.h>
-
- @class Card;
-
- @interface Person : NSManagedObject
-
- @property (nonatomic, retain) NSString * name;
- @property (nonatomic, retain) NSNumber * age;
- @property (nonatomic, retain) Card *card;
-
- @end
Person.m
- #import "Person.h"
-
- @implementation Person
-
- @dynamic name;
- @dynamic age;
- @dynamic card;
-
- @end
Card.h
- #import <Foundation/Foundation.h>
- #import <CoreData/CoreData.h>
-
- @class Person;
-
- @interface Card : NSManagedObject
-
- @property (nonatomic, retain) NSString * no;
- @property (nonatomic, retain) Person *person;
-
- @end
Card.m
- #import "Card.h"
- #import "Person.h"
-
- @implementation Card
-
- @dynamic no;
- @dynamic person;
-
- @end
那麼往數據庫中添加數據的時候就應該寫了:
- Person *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];
- person.name = @"MJ";
- person.age = [NSNumber numberWithInt:27];
-
- Card *card = [NSEntityDescription insertNewObjectForEntityForName:@」Card" inManagedObjectContext:context];
- card.no = @」4414245465656";
- person.card = card;
- // 最後調用[context save&error];保存數據
說到這裏,整個Core Data框架的入門就結束了,其實Core Data還遠不止這些功能,它還支持自動撤銷機制,一對多關聯等,這裏就不一一介紹了