iOS-CoreData使用

1.創建文件
1-1.新建可視化的dataModel

新建文件 -> core data -> Data Model -> .xcdatamodeld (格式)

在.xcdatamodeld可視化界面,Add Entity 創建實體。
實體,就是跟數據庫進行映射的對象。

NSManagedObject — 對應數據庫中的一條記錄。

2-2.新建NSManagedObject

選中某個Entity,點擊Editor,Create NSManagedObject Subclass…
NSManagedObject 是對應着Entity,管理實體對象的代碼。
如下圖:
在這裏插入圖片描述

3.api說明
NSManagedObjectContext 管理對象,上下文,持久性存儲模型對象,處理數據與應用的交互
NSManagedObjectModel 被管理的數據模型,數據結構
NSPersistentStoreCoordinator 添加數據庫,設置數據存儲的名字,位置,存儲方式
NSManagedObject 被管理的數據記錄
NSFetchRequest 數據請求
NSEntityDescription 表格實體結構
4.增刪改查
打開數據庫,初始化環境
/**
 *  打開數據庫
 */
- (void)openDB
{
    /*
     回顧SQLite的操作方式(持久化)
     
     1. opendb打開數據庫,如果第一次運行,會在沙盒中創建數據庫
     2. 打開數據庫之後,會生成一個數據庫連接的句柄->_db,後續的數據庫操作均基於該句柄進行
     3. 創建數據表(IF NOT EXISTS)
     
     ** Core Data的操作方式
     1. 將所有定義好的數據模型文件合併成爲一個數據模型(NSManagedObjectModel)
        建立起針對實體對應的數據表的SQL語句,以便創建數據表
     2. 用數據模型來創建持久化存儲調度,此時就具備了創建表的能力
     3. 爲存儲調度添加持久化的數據存儲(SQLite數據庫),如果沒有,新建並創建數據表
        如果已經存在,直接打開數據庫。
     
        在打開數據庫之後,會判斷實體當前的結構與數據表的描述結構是否一致,如果不一致,會提示打開失敗!
     */
    // 創建數據庫
    // 1. 實例化數據模型(將所有定義的模型都加載進來)
    // merge——合併
    NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
    
    // 2. 實例化持久化存儲調度,要建立起橋樑,需要模型
    NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
    
    // 3. 添加一個持久化的數據庫到存儲調度
    // 3.1 建立數據庫保存在沙盒的URL
    NSArray *docs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [docs[0] stringByAppendingPathComponent:@"my.db"];
    NSURL *url = [NSURL fileURLWithPath:path];
    
    // 3.2 打開或者新建數據庫文件
    // 如果文件不存在,則新建之後打開
    // 否者直接打開數據庫
    NSError *error = nil;
    [store addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error];
    
    if (error) {
        NSLog(@"打開數據庫出錯 - %@", error.localizedDescription);
    } else {
        NSLog(@"打開數據庫成功!");
        
        _context = [[NSManagedObjectContext alloc] init];
        
        _context.persistentStoreCoordinator = store;
    }
}
刪除
#pragma mark - 數據庫操作方法

/**
 *  刪除記錄
 */
- (void)removePerson
{
    // 1. 實例化查詢請求
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
    
    // 2. 設置謂詞條件
    request.predicate = [NSPredicate predicateWithFormat:@"name = '張老頭'"];
    
    // 3. 由上下文查詢數據
    NSArray *result = [_context executeFetchRequest:request error:nil];
    
    // 4. 輸出結果
    for (Person *person in result) {
        NSLog(@"%@ %@ %@", person.name, person.age, person.phoneNo);
        
        // 刪除一條記錄
        [_context deleteObject:person];
        break;
    }
    
    // 5. 通知_context保存數據
    if ([_context save:nil]) {
        NSLog(@"刪除成功");
    } else {
        NSLog(@"刪除失敗");
    }
}
更新
/**
 *  更新數據
 *
 *  在常規開發中,應該首先加載所有的數據,幫頂到UITableView中,該數組中保存所有的Person記錄,
 *  如果是這種情況,在修改個人記錄時,是無需再次去查詢數據庫的。
 *
 *  在實際開發中,通常是從表格中選中某一行,獲取到對應的NSManagedObject,然後進行修改
 *  如此,便可以只修改唯一一條記錄了。
 */
- (void)updatePerson
{
    // 1. 實例化查詢請求
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Book"];
    
    // 2. 設置謂詞條件
    request.predicate = [NSPredicate predicateWithFormat:@"author CONTAINS '大忽悠'"];
    
    // 3. 由上下文查詢數據
    NSArray *result = [_context executeFetchRequest:request error:nil];
    
    // 4. 輸出結果
    for (Book *book in result) {
        NSLog(@"%@ %@ %@", book.name, book.author, book.price);
        
        // 更新書名
        book.name = @"西遊記";
    }
    
    // 通知上下文保存保存
    [_context save:nil];
}
查詢
/**
 *  查詢所有用戶記錄
 */
- (void)allPersons
{
    // 1. 實例化一個查詢(Fetch)請求
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
    
    // 3. 條件查詢,通過謂詞來實現的
//    request.predicate = [NSPredicate predicateWithFormat:@"age < 60 && name LIKE '*五'"];
    // 在謂詞中CONTAINS類似於數據庫的 LIKE '%王%'
//    request.predicate = [NSPredicate predicateWithFormat:@"phoneNo CONTAINS '1'"];
    // 如果要通過key path查詢字段,需要使用%K
//    request.predicate = [NSPredicate predicateWithFormat:@"%K CONTAINS '1'", @"phoneNo"];
    // 直接查詢字表中的條件
    
    // 2. 讓_context執行查詢數據
    NSArray *array = [_context executeFetchRequest:request error:nil];
    
    for (Person *p in array) {
        NSLog(@"%@ %@ %@", p.name, p.age, p.phoneNo);
        
        // 在CoreData中,查詢是懶加載的
        // 在CoreData本身的SQL查詢中,是不使用JOIN的,不需要外鍵
        // 這種方式的優點是:內存佔用相對較小,但是磁盤讀寫的頻率會較高
        for (Book *b in p.books) {
            NSLog(@"%@ %@ %@", b.name, b.price, b.author);
        }
    }
    
//    for (Book *b in array) {
//        NSLog(@"%@ %@ %@", b.name, b.price, b.author);
//    }
}
新增
/**
 新增個人記錄
 */
- (void)addPerson
{
    /**
     回顧SQL新增記錄的過程
     
     1. 拼接一個INSERT的SQL語句
     2. 執行SQL
     */
    // 1. 實例化並讓context“準備”將一條個人記錄增加到數據庫
    Person *p = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:_context];
    
    // 2. 設置個人信息
    p.name = @"張老頭";
    p.age = @10;
    p.phoneNo = @"100";
    p.image = UIImagePNGRepresentation([UIImage imageNamed:@"頭像1"]);
    
    // 3. 新增書,實例化並通知上下文準備加書
    Book *b = [NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:_context];
    b.name = @"太極真經";
    b.price = @20000.99;
    b.author = @"太極忽悠";
    
    Book *b2 = [NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:_context];
    b2.name = @"一陽神功";
    b2.price = @0.99;
    b2.author = @"老忽悠";

    NSSet *bookSet = [NSSet setWithObjects:b, b2, nil];
    p.books = bookSet;
    
    // 3. 保存(讓context保存當前的修改)
    if ([_context save:nil]) {
        NSLog(@"新增成功");
    } else {
        NSLog(@"新增失敗");
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章