Core Data是iOS5之後才出現的一個框架,提供了直接使用SQLite資料庫的大部分靈活性,它提供了物件-關係對映(ORM)的功能,即能夠將OC物件轉化成資料,儲存在SQLite資料庫檔案中,也能夠將儲存在資料庫中的資料還原成OC物件,通過CoreData管理應用程式的資料模型,可以極大程度減少需要編寫的程式碼數量!
示例Demo:CoreDataLearn
1、首先建立一個coreData 模型檔案:系統建立或者自己建立
2、在data Model 中建立專案中需要用到的實體(Entities),例如,建立一個Student 實體(第一字母必須是大寫),以及新增一些name、age、sex 等屬性,如下圖
3、生成對應實體的實體類,在此之前要注意下圖兩個設定部分,否則會引起崩潰現象
4、生成上下文 關聯資料庫
- NSManagedObjectContext 管理物件,上下文,永續性儲存模型物件,處理資料與應用的互動
- NSManagedObjectModel 被管理的資料模型,資料結構
- NSPersistentStoreCoordinator 新增資料庫,設定資料儲存的名字,位置,儲存方式
- NSManagedObject 被管理的資料記錄
- NSFetchRequest 資料請求
- NSEntityDescription 表格實體結構
①、自己建立模型檔案時需要以下程式碼來手動生成上下文,關聯資料庫
//建立資料庫
- (void)createSqlite{
//1、建立模型物件
//獲取模型路徑
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
//根據模型檔案建立模型物件
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
//2、建立持久化儲存助理:資料庫
//利用模型物件建立助理物件
NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
//資料庫的名稱和路徑
NSString *docStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *sqlPath = [docStr stringByAppendingPathComponent:@"coreData.sqlite"];
NSLog(@"資料庫 path = %@", sqlPath);
NSURL *sqlUrl = [NSURL fileURLWithPath:sqlPath];
NSError *error = nil;
//設定資料庫相關資訊 新增一個持久化儲存庫並設定型別和路徑,NSSQLiteStoreType:SQLite作為儲存庫
[store addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:sqlUrl options:nil error:&error];
if (error) {
NSLog(@"新增資料庫失敗:%@",error);
} else {
NSLog(@"新增資料庫成功");
}
//3、建立上下文 儲存資訊 對資料庫進行操作
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
//關聯持久化助理
context.persistentStoreCoordinator = store;
_context = context;
}
複製程式碼
②、系統建立模型檔案時會自動生成關聯資料庫的程式碼,在iOS10以下和iOS10之後生成的不一樣,出現了一個新類NSPersistentContainer。
NSPersistentContainer是一個容器,封裝了應用程式中的CoreData Stack(核心資料棧堆),簡化了建立和管理的核心堆疊的資料處理建立NSManagedObjectModel,NSPersistentStoreCoordinator,NSManagedObjectContext。詳情可以看看這篇文章:blog.csdn.net/u013263917/…
AppDelegate * appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
NSPersistentContainer * container = appDelegate.persistentContainer;
//返回沙盒中儲存資料庫的資料夾URL路徑,這是一個靜態方法,表示資料庫的檔案路徑是唯一的
NSURL * url = [NSPersistentContainer defaultDirectoryURL];
NSManagedObjectContext *viewContext = container.viewContext;
NSManagedObjectModel *managedObjectModel = container.managedObjectModel;
NSPersistentStoreCoordinator *persistentStoreCoordinator = container.persistentStoreCoordinator;
//使用儲存排程器快速在多執行緒中運算元據庫,效率非常高(比主執行緒操作塊50倍!!!)
- (void)performBackgroundTask:(void (^)(NSManagedObjectContext *))block;
複製程式碼
5.增刪改查排
- 寫入資料
// 1.根據Entity名稱和NSManagedObjectContext獲取一個新的繼承於NSManagedObject的子類Student
Student * student = [NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:_context];
//2.根據表Student中的鍵值,給NSManagedObject物件賦值
student.name = [NSString stringWithFormat:@"Mr-%d",arc4random()%100];
student.age = arc4random()%20;
student.sex = arc4random()%2 == 0 ? @"美女" : @"帥哥" ;
student.height = arc4random()%180;
student.number = arc4random()%100
// 3.儲存插入的資料
NSError *error = nil;
if ([_context save:&error]) {
[self alertViewWithMessage:@"資料插入到資料庫成功"];
}else{
[self alertViewWithMessage:[NSString stringWithFormat:@"資料插入到資料庫失敗, %@",error]];
}
複製程式碼
- 刪除資料
- (void)deleteData{
//建立刪除請求
NSFetchRequest *deleRequest = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
//刪除條件
NSPredicate *pre = [NSPredicate predicateWithFormat:@"age < %d", 10];
deleRequest.predicate = pre;
//返回需要刪除的物件陣列
NSArray *deleArray = [_context executeFetchRequest:deleRequest error:nil];
//從資料庫中刪除
for (Student *stu in deleArray) {
[_context deleteObject:stu];
}
NSError *error = nil;
//儲存--記住儲存
if ([_context save:&error]) {
[self alertViewWithMessage:@"刪除 age < 10 的資料"];
}else{
NSLog(@"刪除資料失敗, %@", error);
}
}
複製程式碼
- 更新修改
//更新,修改
- (void)updateData{
//建立查詢請求
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
NSPredicate *pre = [NSPredicate predicateWithFormat:@"sex = %@", @"帥哥"];
request.predicate = pre;
//傳送請求
NSArray *resArray = [_context executeFetchRequest:request error:nil];
//修改
for (Student *stu in resArray) {
stu.name = @"且行且珍惜_iOS";
}
//儲存
NSError *error = nil;
if ([_context save:&error]) {
[self alertViewWithMessage:@"更新所有帥哥的的名字為“且行且珍惜_iOS”"];
}else{
NSLog(@"更新資料失敗, %@", error);
}
}
複製程式碼
- 讀取查詢
//讀取查詢
- (void)readData{
/* 謂詞的條件指令
1.比較運算子 > 、< 、== 、>= 、<= 、!=
例:@"number >= 99"
2.範圍運算子:IN 、BETWEEN
例:@"number BETWEEN {1,5}"
@"address IN {'shanghai','nanjing'}"
3.字串本身:SELF
例:@"SELF == 'APPLE'"
4.字串相關:BEGINSWITH、ENDSWITH、CONTAINS
例: @"name CONTAIN[cd] 'ang'" //包含某個字串
@"name BEGINSWITH[c] 'sh'" //以某個字串開頭
@"name ENDSWITH[d] 'ang'" //以某個字串結束
5.萬用字元:LIKE
例:@"name LIKE[cd] '*er*'" //*代表萬用字元,Like也接受[cd].
@"name LIKE[cd] '???er*'"
*注*: 星號 "*" : 代表0個或多個字元
問號 "?" : 代表一個字元
6.正規表示式:MATCHES
例:NSString *regex = @"^A.+e$"; //以A開頭,e結尾
@"name MATCHES %@",regex
注:[c]*不區分大小寫 , [d]不區分發音符號即沒有重音符號, [cd]既不區分大小寫,也不區分發音符號。
7. 合計操作
ANY,SOME:指定下列表示式中的任意元素。比如,ANY children.age < 18。
ALL:指定下列表示式中的所有元素。比如,ALL children.age < 18。
NONE:指定下列表示式中沒有的元素。比如,NONE children.age < 18。它在邏輯上等於NOT (ANY ...)。
IN:等於SQL的IN操作,左邊的表達必須出現在右邊指定的集合中。比如,name IN { 'Ben', 'Melissa', 'Nick' }。
提示:
1. 謂詞中的匹配指令關鍵字通常使用大寫字母
2. 謂詞中可以使用格式字串
3. 如果通過物件的key
path指定匹配條件,需要使用%K
*/
//建立查詢請求
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
//查詢條件
NSPredicate *pre = [NSPredicate predicateWithFormat:@"sex = %@", @"美女"];
request.predicate = pre;
// 從第幾頁開始顯示
// 通過這個屬性實現分頁
//request.fetchOffset = 0;
// 每頁顯示多少條資料
//request.fetchLimit = 6;
//傳送查詢請求
NSArray *resArray = [_context executeFetchRequest:request error:nil];
[self alertViewWithMessage:@"查詢所有的美女"];
}
複製程式碼
- 排序
//排序
- (void)sort{
//建立排序請求
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
//例項化排序物件
NSSortDescriptor *ageSort = [NSSortDescriptor sortDescriptorWithKey:@"age"ascending:YES];
NSSortDescriptor *numberSort = [NSSortDescriptor sortDescriptorWithKey:@"number"ascending:YES];
request.sortDescriptors = @[ageSort,numberSort];
//傳送請求
NSError *error = nil;
NSArray *resArray = [_context executeFetchRequest:request error:&error];
if (error == nil) {
[self alertViewWithMessage:@"按照age和number排序"];
}else{
NSLog(@"排序失敗, %@", error);
}
}
複製程式碼
CoreData除錯:
開啟Product,選擇Edit Scheme. 選擇Arguments,在下面的ArgumentsPassed On Launch中新增下面兩個選項,如圖: (1)-com.apple.CoreData.SQLDebug (2)1
示例Github:CoreDataLearn
如果需要跟我交流的話: ※ Github: github.com/wsl2ls ※ 個人部落格:wsl2ls.github.io ※ 簡書:www.jianshu.com/u/e15d1f644… ※ 微信公眾號:iOS2679114653 ※ QQ:1685527540