CoreData是iOS5之後新出來的的一個框架, 是對SQLite進行一層封裝升級後的一種數據持久化方式。
它提供了對象<-->關系
映射的功能,即能夠將OC對象轉化為數據存儲到SQLite數據庫文件中,同時也能將數據庫中的數據還原成OC對象。相較於SQLite,我們使用CoreData就不需要再編寫任何SQL語句,再也不去糾結SQL語句怎麼寫了O(∩_∩)O哈~。
PersistentObjectStore
:存儲持久對象的數據庫(例如SQLite,注意CoreData也支持其他類型的數據存儲,例如xml、二進制數據等)。ManagedObjectModel
:對象模型,對應Xcode中創建的模型文件。PersistentStoreCoordinator
:對象模型和實體類之間的轉換協調器,用於管理不同存儲對象的上下文。ManagedObjectContext
:對象管理上下文,負責實體對象和數據庫之間的交互。
最底層的就是PersistentObjectStore
,也就是我們實際存儲數據的結構;
圖中的模型就是ManagedObjectModel
,就是數據轉化為對象的模板;
以SQLite數據庫為例:
這些還是要在使用中進行加深理解
CoreData.framework
#import
導入頭文件<CoreData/CoreData.h>
看上面的圖就知道,我們需要首先創建一個數據模板,即ManagedObjectModel
點擊Next,會進入一個數據模板文件的選擇打鉤,再點Next,會進入一個實體的選擇打鉤,選完點Next就會自動生成對象模型文件。
NSManagedObject
,每個NSManagedObject
對象對應著數據庫中一條記錄。@dynamic
代表具體屬性實現,具體實現細節不需要開發人員關心。ManagedObjectContext
可以細分為:- (NSManagedObjectContext *)createDbContext{
//打開模型文件,參數為nil則打開包中所有模型文件並合並成一個
NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
//創建數據解析器
NSPersistentStoreCoordinator *storeCoordinator =
[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
//創建數據庫保存路徑
NSString *dir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject;
NSString *path = [dir stringByAppendingPathComponent:@"myDatabase.db"];
NSURL *url = [NSURL fileURLWithPath:path];
//添加SQLite持久存儲到解析器
NSError *error;
[storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:url
options:nil
error:&error];
NSManagedObjectContext *context = nil;
if( !error ){
//創建對象管理上下文,並設置數據解析器
context = [[NSManagedObjectContext alloc] init];
context.persistentStoreCoordinator = storeCoordinator;
NSLog(@"數據庫打開成功!");
}else{
NSLog(@"數據庫打開失敗!錯誤:%@",error.localizedDescription);
}
return context;
}
插入數據我們需要創建一個實體對象,並把這個對象關聯上對象管理器,我們創建實體對象需要使用到NSEntityDescription
(實體描述類)的類方法
- (void)addClassTest
{
//添加一個對象
Classes *classes = [NSEntityDescription insertNewObjectForEntityForName:@"Classes"
inManagedObjectContext:self.context];
classes.c_id = 301;
classes.c_name = @"高三(1)班";
NSError *error;
//保存上下文,這裡需要注意,增、刪、改操作完最後必須調用管理對象上下文的保存方法,否則操作不會執行。
if (![self.context save:&error]) {
NSLog(@"添加過程中發生錯誤,錯誤信息:%@!",error.localizedDescription);
}
}
- (void)removeClasses:(Classes *classes){
[self.context deleteObject:classes];
NSError *error;
if (![self.context save:&error]) {
NSLog(@"刪除過程中發生錯誤,錯誤信息:%@!",error.localizedDescription);
}
}
NSFetchRequest
:獲取數據的請求NSPredicate
:請求的謂詞,也就是獲取數據的要求例如查找用戶名為“Binger”的微博(一個微博只能屬於一個用戶),通過keypath查詢:
- (NSArray *)getStatusByUserName:(NSString *)name{
//創建查詢請求
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Status"];
//創建謂詞,設置獲取數據的條件
request.predicate = [NSPredicate predicateWithFormat:@"user.name=%@",name];
//執行對象管理上下文的查詢方法
NSArray *array = [self.context executeFetchRequest:request error:nil];
return array;
}
例如查找發送微博內容中包含“Watch”並且用戶昵稱為“小娜”的用戶(一個用戶有多條微博)
- (NSArray *)getUsersByStatusText:(NSString *)text screenName:(NSString *)screenName{
//創建查詢請求
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Status"];
//設置查詢條件
request.predicate = [NSPredicate predicateWithFormat:@"text LIKE '*Watch*'",text];
//獲取查詢結果
NSArray *statuses = [self.context executeFetchRequest:request error:nil];
//下面是用謂詞對上面的結果進行過濾
NSPredicate *userPredicate = [NSPredicate predicateWithFormat:@"user.screenName=%@",screenName];
//對查詢結果再進行過濾
NSArray *users = [statuses filteredArrayUsingPredicate:userPredicate];
return users;
}
只需要拿到對應的關聯對象,直接修改,然後保存
- (void)modifyClasses:(Classes *)classes
{
classes.name = @"吊炸天畢業(1)班";
NSError *error;
if (![self.context save:&error]) {
NSLog(@"修改過程中發生錯誤,錯誤信息:%@",error.localizedDescription);
}
}
Product
->Scheme
Scheme
->Edit Scheme
Edit Scheme
->Run
Run
->Arguments
然後在運行程序過程中,如果操作了數據庫,就會將SQL語句打印在輸出面板。
注意:如果模型發生了變化,此時可以重新生成實體類文件,但是所生成的數據庫並不會自動更新,這時需要考慮重新生成數據庫並遷移原有的數據。