iOS CoreData (一) 增刪改查

且行且珍惜_iOS發表於2018-12-06

Core Data是iOS5之後才出現的一個框架,提供了直接使用SQLite資料庫的大部分靈活性,它提供了物件-關係對映(ORM)的功能,即能夠將OC物件轉化成資料,儲存在SQLite資料庫檔案中,也能夠將儲存在資料庫中的資料還原成OC物件,通過CoreData管理應用程式的資料模型,可以極大程度減少需要編寫的程式碼數量!

示例Demo:CoreDataLearn

增刪改查.gif

1、首先建立一個coreData 模型檔案:系統建立或者自己建立

系統建立模型檔案.png

自己建立模型檔案.png

2、在data Model 中建立專案中需要用到的實體(Entities),例如,建立一個Student 實體(第一字母必須是大寫),以及新增一些name、age、sex 等屬性,如下圖

建立實體.png

3、生成對應實體的實體類,在此之前要注意下圖兩個設定部分,否則會引起崩潰現象

注意1.png

注意2.png

建立實體類.png

建立實體類.gif

實體類的四個檔案.png

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/…

iOS10以下系統建立模型檔案時自動生成關聯資料庫的程式碼(轉摘).jpeg

iOS10之後系統自動生成的廣聯資料庫的程式碼.png

NSPersistentContainer.png


    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

CoreData除錯.png

示例Github:CoreDataLearn

如果需要跟我交流的話: ※ Github: github.com/wsl2ls ※ 個人部落格:wsl2ls.github.io ※ 簡書:www.jianshu.com/u/e15d1f644… ※ 微信公眾號:iOS2679114653 ※ QQ:1685527540

相關文章