Core Data是一個功能強大的層,位於SQLite數據庫之上,它避免了SQL的複雜性,能讓我們以更自然的方式與數據庫進行交互。Core Data將數據庫行轉換爲OC對象(託管對象)來實現,這樣無需任何SQL知識就能操作他們。
Core Data位於MVC設計模式中的模型層,一般需要在設備上存儲結構化數據時,考慮使用SQLite或是序列化等方法,而Core Data是這兩種方法的混合體,並增加了一些功能,提供了SQL強大威力,但是用起來又和序列化一樣簡單。Core Data能將應用程序中的對象直接保存到數據庫中,無需進行復雜的查詢,也無需確保對象的屬性名和數據庫字段名對應,這一切都由Core Data完成。
Core Data的核心——託管對象
託管對象是要存儲到數據庫中的對象的一種表示,可以看成是SQL記錄,它通常包含一些字段,這些字段與應用程序中要存儲的對象的屬性進行匹配,創建託管對象後,必須將氣託管到託管對象上下文中,然後纔可以存儲到數據庫中。
託管對象上下文:
託管對象上下文包含所有的託管對象,這些託管對象已經爲提交給數據庫準備就緒,在託管對象上下文中,可以添加、修改和刪除託管對象,這一層相當於應用程序和數據庫之間的緩衝區。
託管對象表:
託管對象表描述了數據庫的架構(schema),供託管對象上下文與數據庫交互時使用。託管對象表包含一些列實體描述,每個實體都描述了一個數據庫表,用於將託管對象映射到數據庫條目。
下面來創建一個Core Data
首先要保證引入了CoreData.framwork框架到項目中,然後新建模型文件,New File——Core Data中的Data Model,然後命名爲CDJournal.Xcdatamodel,這裏我們做一個簡單的記錄流水賬的程序。
接下來是定義數據庫實體,選中CDJournal.Xcdatamodel文件打開表編輯器,點擊添加一個名爲Entry的實體,然後可以爲實體添加屬性並指定屬性的數據類型。還可以創建其他實體,如果一個實體包含另一個實體,可通過拖放建立關係,類似於SQL外鍵,比如建立一個Author實體可以有多個Entry。建立實體及屬性如下圖:
創建完實體後必須生成表示數據庫對象的類,使我們能在代碼中表示實體,選擇Entry實體,然後選擇菜單Editor——Create NSManagedObject Subclass,點擊create,就完成了。完成後可以看到工程中多了一個Entry的h和m文件,這就是Core Data模型中的實體對象。基本準備工作就完成了,如下是工程目錄:
現在開始編寫初始化Core Data模型的代碼
首先,在AppDelegate.h中聲明Core Data需要的對象,代碼如下:
- #import <UIKit/UIKit.h>
- //引入CoreData框架
- #import <CoreData/CoreData.h>
- @classViewController;
- @interface AppDelegate : UIResponder <UIApplicationDelegate]]>
- @property (strong, nonatomic) UIWindow *window;
- @property (strong, nonatomic) ViewController *viewController;
- //數據模型對象
- @property(strong,nonatomic) NSManagedObjectModel *managedObjectModel;
- //上下文對象
- @property(strong,nonatomic) NSManagedObjectContext *managedObjectContext;
- //持久性存儲區
- @property(strong,nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- //初始化Core Data使用的數據庫
- -(NSPersistentStoreCoordinator *)persistentStoreCoordinator;
- //managedObjectModel的初始化賦值函數
- -(NSManagedObjectModel *)managedObjectModel;
- //managedObjectContext的初始化賦值函數
- -(NSManagedObjectContext *)managedObjectContext;
- @end
然後在.m文件中實現定義的方法:
- -(NSManagedObjectModel *)managedObjectModel
- {
- if (managedObjectModel != nil) {
- returnmanagedObjectModel;
- }
- managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
- return managedObjectModel;
- }
- -(NSPersistentStoreCoordinator *)persistentStoreCoordinator
- {
- if (persistentStoreCoordinator != nil) {
- returnpersistentStoreCoordinator;
- }
- //得到數據庫的路徑
- NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
- //CoreData是建立在SQLite之上的,數據庫名稱需與Xcdatamodel文件同名
- NSURL *storeUrl = [NSURL fileURLWithPath:[docs stringByAppendingPathComponent:@"CDJournal.sqlite"]];
- NSError *error = nil;
- persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:[self managedObjectModel]];
- if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
- NSLog(@"Error: %@,%@",error,[error userInfo]);
- }
- returnpersistentStoreCoordinator;
- }
- -(NSManagedObjectContext *)managedObjectContext
- {
- if (managedObjectContext != nil) {
- return managedObjectContext;
- }
- NSPersistentStoreCoordinator *coordinator =[self persistentStoreCoordinator];
- if (coordinator != nil) {
- managedObjectContext = [[NSManagedObjectContext alloc]init];
- [managedObjectContext setPersistentStoreCoordinator:coordinator];
- }
- return managedObjectContext;
- }
另外,爲了保證需要存儲的數據不丟失,添加如下代碼:
- //這個方法定義的是當應用程序退到後臺時將執行的方法,按下home鍵執行(通知中心來調度)
- //實現此方法的目的是將託管對象上下文存儲到數據存儲區,防止程序退出時有未保存的數據
- - (void)applicationWillTerminate:(UIApplication *)application
- {
- NSError *error;
- if (managedObjectContext != nil) {
- //hasChanges方法是檢查是否有未保存的上下文更改,如果有,則執行save方法保存上下文
- if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
- NSLog(@"Error: %@,%@",error,[error userInfo]);
- abort();
- }
- }
- }
然後對xib文件進行佈局並連接IBOutlet和IBAction
ViewController.h代碼如下:
- #import <UIKit/UIKit.h>
- #import "AppDelegate.h"
- @interface ViewController : UIViewController
- @property (retain, nonatomic) IBOutletUITextField *titleTextField;
- @property (retain, nonatomic) IBOutletUITextField *contentTextField;
- @property (strong,nonatomic) AppDelegate *myDelegate;
- @property (strong,nonatomic) NSMutableArray *entries;
- //單擊按鈕後執行數據保存操作
- - (IBAction)addToDB:(id)sender;
- //單擊按鈕後執行查詢操作
- - (IBAction)queryFromDB:(id)sender;
- //當通過鍵盤在UITextField中輸入完畢後,點擊屏幕空白區域關閉鍵盤的操作
- -(IBAction)backgroundTapped:(id)sender;
- @end
ViewController.m代碼如下:
- #import "ViewController.h"
- #import "Entry.h"
- @interfaceViewController ()
- @end
- @implementation ViewController
- @synthesize titleTextField;
- @synthesize contentTextField;
- @synthesize myDelegate = _myDelegate;
- @synthesize entries = _entries;
- - (void)viewDidLoad
- {
- [superviewDidLoad];
- //獲取當前應用程序的委託(UIApplication sharedApplication爲整個應用程序上下文)
- self.myDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
- }
- - (void)viewDidUnload
- {
- [selfsetTitleTextField:nil];
- [selfsetContentTextField:nil];
- [superviewDidUnload];
- // Release any retained subviews of the main view.
- }
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
- {
- return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
- }
- - (void)dealloc {
- [titleTextFieldrelease];
- [contentTextFieldrelease];
- [superdealloc];
- }
- //單擊按鈕後執行數據保存操作
- - (IBAction)addToDB:(id)sender {
- //讓CoreData在上下文中創建一個新對象(託管對象)
- Entry *entry = (Entry *)[NSEntityDescription insertNewObjectForEntityForName:@"Entry" inManagedObjectContext:self.myDelegate.managedObjectContext];
- [entry setTitle:self.titleTextField.text];
- [entry setBody:self.contentTextField.text];
- [entry setCreationDate:[NSDatedate]];
- NSError *error;
- //託管對象準備好後,調用託管對象上下文的save方法將數據寫入數據庫
- BOOL isSaveSuccess = [self.myDelegate.managedObjectContextsave:&error];
- if (!isSaveSuccess) {
- NSLog(@"Error: %@,%@",error,[error userInfo]);
- }else {
- NSLog(@"Save successful!");
- }
- }
- //單擊按鈕後執行查詢操作
- - (IBAction)queryFromDB:(id)sender {
- //創建取回數據請求
- NSFetchRequest *request = [[NSFetchRequest alloc] init];
- //設置要檢索哪種類型的實體對象
- NSEntityDescription *entity = [NSEntityDescription entityForName:@"Entry"inManagedObjectContext:self.myDelegate.managedObjectContext];
- //設置請求實體
- [request setEntity:entity];
- //指定對結果的排序方式
- NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate"ascending:NO];
- NSArray *sortDescriptions = [[NSArray alloc]initWithObjects:sortDescriptor, nil];
- [request setSortDescriptors:sortDescriptions];
- [sortDescriptions release];
- [sortDescriptor release];
- NSError *error = nil;
- //執行獲取數據請求,返回數組
- NSMutableArray *mutableFetchResult = [[self.myDelegate.managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
- if (mutableFetchResult == nil) {
- NSLog(@"Error: %@,%@",error,[error userInfo]);
- }
- self.entries = mutableFetchResult;
- NSLog(@"The count of entry:%i",[self.entriescount]);
- for (Entry *entry inself.entries) {
- NSLog(@"Title:%@---Content:%@---Date:%@",entry.title,entry.body,entry.creationDate);
- }
- [mutableFetchResult release];
- [request release];
- }
- //更新操作
- -(void)updateEntry:(Entry *)entry
- {
- [entry setTitle:self.titleTextField.text];
- [entry setBody:self.contentTextField.text];
- [entry setCreationDate:[NSDatedate]];
- NSError *error;
- BOOL isUpdateSuccess = [self.myDelegate.managedObjectContextsave:&error ];
- if (!isUpdateSuccess) {
- NSLog(@"Error:%@,%@",error,[error userInfo]);
- }
- }
- //刪除操作
- -(void)deleteEntry:(Entry *)entry
- {
- [self.myDelegate.managedObjectContext deleteObject:entry];
- [self.entriesremoveObject:entry];
- NSError *error;
- if (![self.myDelegate.managedObjectContext save:&error]) {
- NSLog(@"Error:%@,%@",error,[error userInfo]);
- }
- }
- //當通過鍵盤在UITextField中輸入完畢後,點擊屏幕空白區域關閉鍵盤的操作
- -(IBAction)backgroundTapped:(id)sender
- {
- [titleTextField resignFirstResponder];
- [contentTextField resignFirstResponder];
- }
- @end
最後運行並填入數據,點擊Add後添加成功
多添加幾條數據後點擊Query便可以查看輸出的查詢結果,在命令行的輸出結果如下:
原文地址:http://blog.csdn.net/ryantang03/article/details/7794226