CoreData 的簡(jiǎn)單使用
之前學(xué)了CoreData, 但是幾周沒(méi)用就忘記了, 這里整理下筆記, 以便忘記的時(shí)候回來(lái)看一下。
本文只記載超詳細(xì)的操作過(guò)程哦!! 原理性的東西寫(xiě)得比較少(旁邊: 明明是自己不會(huì)啊)
保存數(shù)據(jù)的方式
- 偏好設(shè)置
- 歸檔
- sqlite
- CoreData (基于sqlite的封裝, 數(shù)據(jù)保存到一個(gè)數(shù)據(jù)庫(kù)文件)
什么是CoreData[^1]
[^1]: 這段介紹是從傳智播客那里看到的
Core Data 是 iOS5 之后才出現(xiàn)的一個(gè)框架, 它提供了對(duì)象-關(guān)系映射(ORM)的功能, 即能夠將 OC 對(duì)象轉(zhuǎn)化成數(shù)據(jù), 保存在 SQLite 數(shù)據(jù)庫(kù)文件中, 也能夠將保存在數(shù)據(jù)庫(kù)中的數(shù)據(jù)還原成 OC 對(duì)象。在此數(shù)據(jù)操作期間,我們不需要編寫(xiě)任何SQL語(yǔ)句。
CoreData 的簡(jiǎn)單使用操作步驟 (包含3個(gè)部分哦)
第一部分 創(chuàng)建模型
1. 創(chuàng)建模型文件 (相當(dāng)于數(shù)據(jù)庫(kù))
按以下步驟:
- command + N (或右鍵 New File...)
- 選 Core Data
- 選 Data Model
- 創(chuàng)建文件 (文件擴(kuò)展名為 .xcdatamodeld), 將文件命名為 Company
2. 添加實(shí)體 (相當(dāng)于表)
按以下步驟:
- 點(diǎn)擊 Add Entity (添加實(shí)體)
- 將實(shí)體名 Entity 修改為 Employee, 代表公司的員工表
CoreData01.png - 在右端添加員工表的字段 (name, age, height)
CoreData02.png
3. 創(chuàng)建實(shí)體類(lèi) (相當(dāng)于模型類(lèi))
按以下步驟:
- command + N (或右鍵 New File...)
- 選 Core Data
- 選 NSManagedObject subclass
- 接著, Data Model 勾選之前的公司模型 (Company), Entity 勾選之前創(chuàng)建的員工實(shí)體 (Employee), 創(chuàng)建員工的實(shí)體類(lèi)
第二部分 搭建上下文環(huán)境
生成上下文, 關(guān)聯(lián)模型文件生成數(shù)據(jù)庫(kù)
記得導(dǎo)入頭文件 #import <CoreData/CoreData.h> 哦!
開(kāi)發(fā)步驟總結(jié):
- 初始化NSManagedObjectModel對(duì)象, 加載模型文件, 讀取app中的所有實(shí)體信息;
- 初始化NSPersistentStoreCoordinator對(duì)象, 添加持久化庫(kù)(這里采取SQLite數(shù)據(jù)庫(kù));
- 初始化NSManagedObjectContext對(duì)象, 拿到這個(gè)上下文對(duì)象操作實(shí)體, 進(jìn)行CRUD操作.
實(shí)例:
// 從應(yīng)用程序包中加載模型文件
NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
// 傳入模型對(duì)象, 初始化NSPersistentStoreCoordinator
// 持久化存儲(chǔ)調(diào)度器
NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
// 構(gòu)建SQLite數(shù)據(jù)庫(kù)文件的路徑
// 獲取document目錄
NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
// 數(shù)據(jù)庫(kù)保存的路徑
NSString *sqlitePath = [doc stringByAppendingPathComponent:@"company.sqlite"];
NSError *error = nil;
[store addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:sqlitePath] options:nil error:&error];
// 初始化上下文,設(shè)置persistentStoreCoordinator屬性
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
context.persistentStoreCoordinator = store;
第三部分 實(shí)現(xiàn)增刪改查
添加員工信息 (增)
開(kāi)發(fā)步驟總結(jié):
Ⅰ 調(diào)用NSEntityDescription類(lèi)的insertNewObjectForEntityForName: inManagedObjectContext:類(lèi)方法添加新實(shí)體;
Ⅱ 為新實(shí)體設(shè)置屬性;
Ⅲ 調(diào)用NSManagedObjectContext對(duì)象的save:方法執(zhí)行保存.
實(shí)例:
// 創(chuàng)建員工
Employee *employee = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:_context];
// 設(shè)置員工屬性
employee.name = @"ryu";
employee.age = @(22);
employee.height = @(17.6);
// 保存
NSError *error;
[_context save:&error];
查詢(xún)員工信息 (查)
開(kāi)發(fā)步驟總結(jié):
Ⅰ 創(chuàng)建NSFetchRequest對(duì)象;
Ⅱ 設(shè)置NSFetchRequest對(duì)象的entity屬性, 代表將要查詢(xún)的實(shí)體. (該屬性是NSEntityDescription類(lèi))
也可以將第一、二步過(guò)程整合成一步: 直接調(diào)用 NSFetchRequest 類(lèi)的 fetchRequestWithEntityName: 方法創(chuàng)建 NSFetchRequest 對(duì)象
Ⅲ 設(shè)置NSFetchRequest對(duì)象的屬性, 不同屬性會(huì)有不同的效果
| 效果 | NSFetchRequest對(duì)象的屬性 |
|---|---|
| 結(jié)果排序 | sortDescriptors |
| 過(guò)濾查詢(xún) | predicate |
| 分頁(yè)查詢(xún) | fetchLimit fetchOffset |
Ⅳ 調(diào)用NSManagedObjectContext對(duì)象的
executeFetchRequest: error:執(zhí)行查詢(xún)。該查詢(xún)方法將會(huì)返回所有符合條件的實(shí)體組成的NSArray集合.
實(shí)例:
查詢(xún)?nèi)繂T工信息
// 創(chuàng)建一個(gè)請(qǐng)求對(duì)象
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];
NSError *error = nil;
NSArray *emps = [_context executeFetchRequest:request error:&error];
for (Employee *emp in emps) {
NSLog(@"姓名:%@, 年齡:%@, 身高:%@", emp.name, emp.age, emp.height);
}
查詢(xún)結(jié)果進(jìn)行排序 (設(shè)置 NSFetchRequest 對(duì)象的 sortDescriptors 屬性)
// 以年齡進(jìn)行升序排序
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:YES];
request.sortDescriptors = @[sort];
過(guò)濾查詢(xún) (設(shè)置 NSFetchRequest 對(duì)象的 predicate 屬性)
// 查詢(xún)名字叫ryu的信息
NSPredicate *pre = [NSPredicate predicateWithFormat:@"name=%@", @"ryu"];
request.predicate = pre;
// 查詢(xún)年齡大于22, 身高大于16.0的員工信息
NSPredicate *pre = [NSPredicate predicateWithFormat:@"age > %@ AND height > %@", @(22), @(16.0)];
request.predicate = pre;
分頁(yè)查詢(xún)
// 假定有1000條數(shù)據(jù), 每次查詢(xún)5條
// 設(shè)置每次查詢(xún)的條數(shù)
request.fetchLimit = 5;
// 設(shè)置分頁(yè)查詢(xún)起始頁(yè)數(shù) (查詢(xún)的偏移量)
// 從第一頁(yè)開(kāi)始查詢(xún)
request.fetchOffset = 0;
刪除員工信息 (刪)
記住: 要配合上面查詢(xún)一起使用哦
開(kāi)發(fā)步驟總結(jié):
- 獲取要?jiǎng)h除的實(shí)體; 用查詢(xún)方式找到該實(shí)體哦
- 調(diào)用 NSManagedObjectContext 對(duì)象的
- (void)deleteObject:(NSManagedObject *)object;刪除實(shí)體;- 接著調(diào)用 NSManagedObjectContext 對(duì)象的 save: 方法執(zhí)行保存
刪除和更新的過(guò)程超簡(jiǎn)單, 只寫(xiě)操作過(guò)程了, 不附帶實(shí)例(反正估計(jì)沒(méi)人看實(shí)例吧, 因?yàn)橘N出來(lái)的都是關(guān)鍵代碼片段)
更新員工信息 (改)
記住: 要配合上面查詢(xún)一起使用哦
開(kāi)發(fā)步驟總結(jié):
修改實(shí)體
- 獲取要修改的實(shí)體(必須是處于NSManagedObjectContext管理下的實(shí)體); 用查詢(xún)方式找到該實(shí)體哦
- 修改實(shí)體的屬性;
- 接著調(diào)用NSManagedObjectContext對(duì)象的save:方法執(zhí)行保存.

