CoreData是iOS3.0後引入的數據持久化解決方案, 是一種對象關系映射(ORM), 例如java後台中的Hibernate, iOS中ORM框架首先CoreData, 這是官方推薦的 不需要借助第三方框架,實際上是對sqlite的封裝,提供了更高級的持久化方式, 在數據庫操作時, 不需要使用sql語句, 也可以直接操作數據庫
ORM框架的作用:將關系數據庫中的表(實體)轉換成程序中的對象, 其本質還是對數據庫的操作, CoreData將對象關系的映射簡化了
使用CoreData進行數據庫存取並不需要手動創建數據庫, 這個過程完全有CoreData框架完成, 開發人員面對的是模型, 主要的工作就是把模型創建起來, 具體的數據庫如何創建也不用管,
CoreData與SQLite相比較, SQLite比較原始, 操作比較復雜, 使用的是C的函數對數據庫進行的操作, 但是CoreData不能跨平台, SQLite能夠跨平台, 可控性更強, 更加輕量級.
下面簡單的學習下CoreData的使用:
其中 各個對象的作用:(NSManagerObjectContext 比較重要)
Persistent Object Store:可以理解為存儲持久對象的數據庫(例如SQLite,注意Core Data也支持其他類型的數據存儲,例如xml、二進制數據等)。Managed Object Model:對象模型,對應Xcode中創建的模型文件。 Persistent Store Coordinator:對象模型和實體類之間的轉換協調器,用於管理不同存儲對象的上下文。Managed Object Context:對象管理上下文,負責實體對象和數據庫之間的交互。
模型創建的過程中注意:
實體對象不需要創建ID主鍵,Attributes中應該是有意義屬性(創建過程中應該考慮對象的屬性而不是數據庫中表有幾個字段,盡管多數屬性會對應表的字段)。所有的屬性應該指定具體類型(盡管在SQLite中可以不指定),因為實體對象會對應生成ObjC模型類。實體對象中其他實體對象類型的屬性應該通過Relationships建立,並且注意實體之間的對應關系(例如一個用戶有多條微博,而一條微博則只屬於一個用戶,用戶和微博形成一對多的關系)。
每個實體類系統自動生成了4個文件User.h, User.m (User的CoreDataProperties的類目)
需要注意的是以下幾點:
所有的實體類型都繼承於NSManagedObject,每個NSManagedObject對象對應著數據庫中一條記錄。集合屬性(例如User中的status)生成了訪問此屬性的分類方法。 使用@dynamic代表具體屬性實現,具體實現細節不需要開發人員關心。
CoreData的增刪改查的操作主要是基於NSManagerObjectContext, 創建上下文, 保存數據
這裡可以使用Appdelegate提供的NSManagerObjectContext這個對象
// 添加數據 - (IBAction)add:(id)sender { // 用NSEntityDescription創建實體對象 User *user = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:self.managerObjectContext]; user.name = @"Xia"; user.age = @"18"; user.time = [NSDate dateWithTimeIntervalSinceNow:0]; NSError *error; // 保存上下文 if (![self.managerObjectContext save:&error]) { NSLog(@"添加過程中的錯誤信息---%@", error.localizedDescription); } }
注意: 下面有關於NSPredicate拓展
// 查詢數據 - (IBAction)equery:(id)sender { // 查詢獲取請求, 設置查詢哪個實體 EntityName NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"User"]; // NSFetchRequest 有個屬性 謂詞 predicate(NSPredicate類型) // 類似於查詢語句的查詢條件 用來條件查詢 // 查詢 user表中 name是Xia的User request.predicate = [NSPredicate predicateWithFormat:@"name='Xia'"]; // 也可以使用下面的查詢語句格式 // NSString *name = @"Xia"; // request.predicate = [NSPredicate predicateWithFormat:@"name like [cd] %@", name]; NSArray *array = [self.managerObjectContext executeFetchRequest:request error:nil]; }
// 刪除數據 - (IBAction)delete:(id)sender { // 先獲取表裡的所有數據 NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"User"]; NSArray *array = [self.managerObjectContext executeFetchRequest:request error:nil]; // 對表裡數據的數組進行遍歷 for (User *user in array) { // 條件刪除 if ([user.name isEqualToString:@"Xia"]) { [self.managerObjectContext deleteObject:user]; } } NSError *error; // 保存上下文 if (![self.managerObjectContext save:&error]) { NSLog(@"刪除過程中發生的錯誤信息 ----- %@", error.localizedDescription); } }
// 更新數據 - (IBAction)update:(id)sender { // 先獲取某個實體 User *user = [self getUserByUserName:@"Xia"]; // 修改實體的屬性 user.name = @"Yan"; user.age = @"20"; NSError *error; // 保存上下文 if (![self.managerObjectContext save:&error]) { NSLog(@"更新數據發生錯誤 錯誤信息----%@", error.localizedDescription); } } // 通過username 獲取 User實體類 - (User *)getUserByUserName:(NSString *)username { // User *user = [[User alloc] init]; NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"User"]; NSArray *array = [self.managerObjectContext executeFetchRequest:request error:nil]; for (User *auser in array) { if ([auser.name isEqualToString:username]) { return auser; } } return nil; }
NSPredicate用於查詢和過濾
在SQL中作為查詢條件通常用WHERE,但在COREDATA中作為查詢條件就可以用到NSPredicate.
NSPredicate 不單可以和COREDATA中的FetchRequest 配合使用。也可以與NSArray配合使用。
NSPredicate 中支持的關鍵詞和條件符:
如:
NSPredicate * qcondition= [NSPredicate predicateWithFormat:@"salary >= 10000"];
如:
@"employee.name BEGINSWITH[cd] '李'" //姓李的員工
@"employee.name ENDSWITH[c] '夢'" //以夢結束的員工
@"employee.name CONTAINS[d] '宗'" //包含有"宗"字的員工
注:[c]不區分大小寫[d]不區分發音符號即沒有重音符號[cd]既不區分大小寫,也不區分發音符號。
如:
@"salary BWTEEN {5000,10000}"
@"em_dept IN '開發'"
如:
NSArray * test = =[NSArray arrayWithObjects: @"guangzhou", @"beijing", @"shanghai", nil];
@"SELF='beijing'"
LIKE 使用?表示一個字符,*表示多個字符,也可以與c、d 連用。
如:
@"car.name LIKE '?he?'" //四個字符中,中間為he
@"car.name LIKE '*jp'" //以jp結束
如:
NSString *regex = @"^E.+e$";//以E 開頭,以e 結尾的字符。
NSPredicate *pre= [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
if([pre evaluateWithObject: @"Employee"]){
NSLog(@"matches YES");
}else{
NSLog(@"matches NO");
}
如:
@"employee.name = 'john' AND employee.age = 28"
NSPredicate *preTemplate = [NSPredicate predicateWithFormat:@"name==$NAME"];
NSDictionary *dic=[NSDictionary dictionaryWithObjectsAndKeys:
@"Name1", @"NAME",nil];
NSPredicate *pre=[preTemplate predicateWithSubstitutionVariables: dic];
占位符就是字典對象裡的key,因此你可以有多個占位符,只要key 不一樣就可以了。
CoreData的操作會轉換為SQL操作, 在Xcode上設置支持CoreData調試
Product-Scheme-Edit Scheme-Run-Arguments中依次添加兩個參數(注意參數順序不能錯):-com.apple.CoreData.SQLDebug、1。然後在運行程序過程中如果操作了數據庫就會將SQL語句打印在輸出面板
。
最後注意:CoreData線程安全問題 和CoreData的版本遷移問題, 下次有時間再整理