02-CoreData 的增刪改查

葉喬木發表於2019-01-02

CoreData 的增刪改查

基本的增刪改查的操作

1 資料庫的建立

- (void)createDB
{
    
    // 1.1 建立路徑
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"AT_CoreDataDemo1" withExtension:@"momd"];
    // 1.2 根據模型檔案路徑建立模型物件
    NSManagedObjectModel *model = [[NSManagedObjectModel alloc]initWithContentsOfURL:modelURL];
    
    
    // 2.1 建立持久化儲存器 管理資料庫
    // 傳入模型的物件
    NSPersistentStoreCoordinator *storeCoord = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:model];
    
    // 3 資料庫存放的路徑
    // doc 資料夾路徑
    NSString *docStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,  NSUserDomainMask, YES) lastObject];
    // 資料庫路徑
    NSString *sqlPath = [docStr stringByAppendingPathComponent:@"student.sqlite"];
    
    //  4 設定資料庫相關的資訊
    //  儲存器sqlite 型別
    NSError *error = nil;
    [storeCoord addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:sqlPath] options:nil error:&error];
    
    if (!error) {
        NSLog(@"資料庫建立成功--%@",sqlPath);
    }else{
        NSLog(@"資料庫建立失敗");
        
    }
    
    
    // 建立上下文 對資料庫進行操作
    NSManagedObjectContext *context = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType];
    // 關聯協調器
    context.persistentStoreCoordinator = storeCoord;
    // 關聯全域性的上下文 以便於運算元據庫
    _context = context;
    
    
    
}

2 插入資料

// 插入一條資料操作
- (IBAction)insertAction:(UIButton *)sender {
    
    
    // 1.根據Entity名稱和NSManagedObjectContext獲取一個新的繼承於NSManagedObject的子類Student
    
    Student *stu = [NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:_context];
    
    stu.name = [NSString stringWithFormat:@"編號%d",arc4random()% 1000];
    
    stu.age =  [[NSString stringWithFormat:@"%d",arc4random()% 100] integerValue];
    
//    stu.sex = (arc4random()%100) / 2 ? @"男":@"女";
    
    
    //2 查詢所有的請求
    NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
    
    // 執行操作
    NSError *error = nil;
    [_context executeRequest:req error:&error];
    
    [_dataSource removeAllObjects];
    [_dataSource addObjectsFromArray:[_context executeFetchRequest:req error:nil]];
    [self.tableView reloadData];
    
    
    // 3 講資料插入到資料庫
    NSError *error2= nil;
    if ([_context save:&error2]) {
        NSLog(@"儲存資料成功");
    }else{
        NSLog(@"儲存資料失敗");
    }
    


    
    NSLog(@"%@",_dataSource);
    
}

2 更新資料

// 更新資料操作
- (IBAction)updateAction:(UIButton *)sender {
    
    // 1 建立查詢請求
    NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
    
    // 不新增任何條件的查詢就是講所有的資料查詢出來
    // 使用謂詞 過濾條件
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"age > %d", 50];
    
    req.predicate = pre;
    
    // 1.1 請求結果
    NSArray *resArr = [_context executeFetchRequest:req error:nil];
    
    // 2 更新資料
    for (Student *stu in resArr) {
        stu.name = @"標記:年齡已經大於50的人";
    }
    
    [_dataSource removeAllObjects];
    [_dataSource addObjectsFromArray:resArr];
    
    // 3 進行儲存操作
    NSError *error= nil;
    if ([_context save:&error]) {
        NSLog(@"儲存資料成功");
    }else{
        NSLog(@"儲存資料失敗");
    }
 
    
}

3 刪除資料

- (IBAction)deleteAction:(UIButton *)sender {
    // 1 建立刪除請求
    NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
    
    // 不新增任何條件的查詢就是講所有的資料查詢出來
    // 使用謂詞 過濾條件
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"age > %d && age < %d", 40,60];
    req.predicate = pre;
    
    NSArray *resArr = [_context executeFetchRequest:req error:nil];
    
    [_dataSource removeAllObjects];
    [_dataSource addObjectsFromArray:resArr];
    [self.tableView reloadData];
    // 2 查詢出來的資料進行刪除操作
    for (Student *stu in resArr) {
        [_context deleteObject:stu];
    }
    
    
    // 3 進行操作操作
    NSError *error= nil;
    if ([_context save:&error]) {
        NSLog(@"刪除資料成功");
    }else{
        NSLog(@"刪除資料失敗");
    }
    
    
    
}

4 排序資料

- (IBAction)orderAction:(UIButton *)sender {
    
    //建立排序請求
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
    
    //例項化排序物件 將年齡按照升序排列
    NSSortDescriptor *ageSort = [NSSortDescriptor sortDescriptorWithKey:@"age"ascending:YES];
    // 可以新增多個篩選條件
    request.sortDescriptors = @[ageSort];
    
    NSArray *resArray = [_context executeFetchRequest:request error:nil];
    [_dataSource removeAllObjects];
    _dataSource = [NSMutableArray arrayWithArray:resArray];
    [self.tableView reloadData];
    
}

5 查詢資料

// 查詢資料
- (IBAction)queryAction:(UIButton *)sender {
    
    /* 謂詞的條件指令
     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
     
     */
    
    
    // 1 建立查詢請求
    NSFetchRequest *req =[NSFetchRequest fetchRequestWithEntityName:@"Student"];
    
    // 過濾條件
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"age > 80"];
    
    req.predicate = pre;
    
    
    // 通過這個屬性實現分頁
    //request.fetchOffset = 0;
    
    // 每頁顯示多少條資料
    //request.fetchLimit = 6;
    
    NSArray *resArray = [_context executeFetchRequest:req error:nil];
    _dataSource = [NSMutableArray arrayWithArray:resArray];
    [self.tableView reloadData];
    
    
}

6 獲取查詢條件的資料數

在開發過程中,有時候只需要所需資料的count值,如果像之前一樣獲取所有物件載入到記憶體,在去遍歷是比較消耗記憶體的。

蘋果提供了兩種方式,去直接查詢count值,count值的查詢是在資料庫層面完成的,不需要將託管物件載入到記憶體中,避免記憶體的大開銷。

  1. resultType 通過設定NSFetchRequest 物件的resultType 來獲取count 值
    // 1 建立查詢請求
    NSFetchRequest *req =[NSFetchRequest fetchRequestWithEntityName:@"Student"];
    
    // 過濾條件
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"age > 80"];
    
    req.predicate = pre;
    // 設定查詢獲取數量
    req.resultType = NSCountResultType;

    // 只查詢數量 不查詢物件
    NSArray *resArray = [_context executeFetchRequest:req error:nil];
    
    // 執行查詢操作,陣列中只返回一個物件,就是計算出的count 值
    NSInteger count = [resArray.firstObject integerValue];

    NSLog(@"count--%ld",count);
    

2 直接呼叫countForFetchRequest 方法獲取數量

    // 1 建立查詢請求
    NSFetchRequest *req =[NSFetchRequest fetchRequestWithEntityName:@"Student"];
    
    // 過濾條件
    NSPredicate *pre = [NSPredicate predicateWithFormat:@"age > 80"];
    
    req.predicate = pre;
 
    
    // 只查詢數量 不查詢物件
    NSArray *resArray = [_context executeFetchRequest:req error:nil];
    
    // 執行查詢操作,陣列中只返回一個物件,就是計算出的count 值
    
    NSUInteger count = [_context countForFetchRequest:req error:nil];

    NSLog(@"count--%ld",count);

相關文章