簡介
? Core Data是iOS5之后才出現的一個框架,它提供了對象-關系映射(ORM)的功能,即能夠將OC對象轉化成數據,保存在SQLite數據庫文件中,也能夠將保存在數據庫中的數據還原成OC對象。在此數據操作期間,我們不需要編寫任何SQL語句,這個有點類似于著名的Hibernate持久化框架,不過功能肯定是沒有Hibernate強大的。簡單地用下圖描述下它的作用:
左邊是關系模型,即數據庫,數據庫里面有張person表,person表里面有id、name、age三個字段,而且有2條記錄;
右邊是對象模型,可以看到,有2個OC對象;
利用Core Data框架,我們就可以輕松地將數據庫里面的2條記錄轉換成2個OC對象,也可以輕松地將2個OC對象保存到數據庫中,變成2條表記錄,而且不用寫一條SQL語句。
?
模型文件

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屬性也自動補上了
?
?
了解NSManagedObject
?


2.NSManagedObject的工作模式有點類似于NSDictionary對象,通過鍵-值對來存取所有的實體屬性
1>?setValue:forKey:存儲屬性值(屬性名為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"]??
- }??
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還遠不止這些功能,它還支持自動撤銷機制,一對多關聯等,這里就不一一介紹了