你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS 數據持久化 CoreData

iOS 數據持久化 CoreData

編輯:IOS開發綜合

CoreData是iOS3.0後引入的數據持久化解決方案, 是一種對象關系映射(ORM), 例如java後台中的Hibernate, iOS中ORM框架首先CoreData, 這是官方推薦的 不需要借助第三方框架,實際上是對sqlite的封裝,提供了更高級的持久化方式, 在數據庫操作時, 不需要使用sql語句, 也可以直接操作數據庫

ORM框架的作用:將關系數據庫中的表(實體)轉換成程序中的對象, 其本質還是對數據庫的操作, CoreData將對象關系的映射簡化了

使用CoreData進行數據庫存取並不需要手動創建數據庫, 這個過程完全有CoreData框架完成, 開發人員面對的是模型, 主要的工作就是把模型創建起來, 具體的數據庫如何創建也不用管,

CoreData與SQLite相比較, SQLite比較原始, 操作比較復雜, 使用的是C的函數對數據庫進行的操作, 但是CoreData不能跨平台, SQLite能夠跨平台, 可控性更強, 更加輕量級.

 

下面簡單的學習下CoreData的使用:

 

1. 創建工程的時候要勾選 user CoreData

 

 

\

 

 

2. 在Appdelegate中會自動生成以下對象和方法

 

 

\

 

\

 

其中 各個對象的作用:(NSManagerObjectContext 比較重要)

 

Persistent Object Store:可以理解為存儲持久對象的數據庫(例如SQLite,注意Core Data也支持其他類型的數據存儲,例如xml、二進制數據等)。Managed Object Model:對象模型,對應Xcode中創建的模型文件。 Persistent Store Coordinator:對象模型和實體類之間的轉換協調器,用於管理不同存儲對象的上下文。Managed Object Context:對象管理上下文,負責實體對象和數據庫之間的交互。

 

3. 創建實體模型和關系:

 

\\

 

模型創建的過程中注意:

 

實體對象不需要創建ID主鍵,Attributes中應該是有意義屬性(創建過程中應該考慮對象的屬性而不是數據庫中表有幾個字段,盡管多數屬性會對應表的字段)。所有的屬性應該指定具體類型(盡管在SQLite中可以不指定),因為實體對象會對應生成ObjC模型類。實體對象中其他實體對象類型的屬性應該通過Relationships建立,並且注意實體之間的對應關系(例如一個用戶有多條微博,而一條微博則只屬於一個用戶,用戶和微博形成一對多的關系)。

 

4. 根據上面的模型文件(.xcdatamodeld文件)生成具體的實體類.

 

\

 

每個實體類系統自動生成了4個文件User.h, User.m (User的CoreDataProperties的類目)

 

 

\

\

\

 

需要注意的是以下幾點:

 

所有的實體類型都繼承於NSManagedObject,每個NSManagedObject對象對應著數據庫中一條記錄。集合屬性(例如User中的status)生成了訪問此屬性的分類方法。 使用@dynamic代表具體屬性實現,具體實現細節不需要開發人員關心。

5. 創建好實體和關系, 就可以對數據進行增刪改查的操作了:

 

CoreData的增刪改查的操作主要是基於NSManagerObjectContext, 創建上下文, 保存數據

這裡可以使用Appdelegate提供的NSManagerObjectContext這個對象

增加數據: 需要調用NSEntityDescription返回一個實體對象, 然後設置對象的屬性, 保存上下文(進行增刪改操作的時候, 一定要調用管理上下文的保存方法, 否則操作不會執行)

 

// 添加數據
- (IBAction)add:(id)sender {
    // 用NSEntityDescription創建實體對象
    User *user = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:self.managerObjectContext];
    user.name = @"Xia";
    user.age = @"18";
    user.time = [NSDate dateWithTimeIntervalSinceNow:0];
    NSError *error;
    // 保存上下文
    if (![self.managerObjectContext save:&error]) {
        NSLog(@"添加過程中的錯誤信息---%@", error.localizedDescription);
    }
}

 

查詢數據: 通過謂詞來實現的, 首先創建一個請求, 設置請求的謂詞, 調用上下文執行

 

注意: 下面有關於NSPredicate拓展

 

// 查詢數據
- (IBAction)equery:(id)sender {
    // 查詢獲取請求, 設置查詢哪個實體 EntityName
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"User"];
    // NSFetchRequest 有個屬性 謂詞 predicate(NSPredicate類型)
    // 類似於查詢語句的查詢條件   用來條件查詢
    
    // 查詢 user表中 name是Xia的User
    request.predicate = [NSPredicate predicateWithFormat:@"name='Xia'"];
    
    // 也可以使用下面的查詢語句格式
//    NSString *name = @"Xia";
//    request.predicate = [NSPredicate predicateWithFormat:@"name like [cd] %@", name];
    NSArray *array = [self.managerObjectContext executeFetchRequest:request error:nil];
}

 

刪除數據

 

// 刪除數據
- (IBAction)delete:(id)sender {
    
    // 先獲取表裡的所有數據
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"User"];
    NSArray *array = [self.managerObjectContext executeFetchRequest:request error:nil];
    
    // 對表裡數據的數組進行遍歷
    for (User *user in array) {
        // 條件刪除
        if ([user.name isEqualToString:@"Xia"]) {
            [self.managerObjectContext deleteObject:user];
        }
        
    }
    
    NSError *error;
    // 保存上下文
    if (![self.managerObjectContext save:&error]) {
        NSLog(@"刪除過程中發生的錯誤信息 ----- %@", error.localizedDescription);
    }
}
 

 

更新數據

 

 

// 更新數據
- (IBAction)update:(id)sender {
    // 先獲取某個實體
    User *user = [self getUserByUserName:@"Xia"];
    
    // 修改實體的屬性
    user.name = @"Yan";
    user.age = @"20";
    
    NSError *error;
    // 保存上下文
    if (![self.managerObjectContext save:&error]) {
        NSLog(@"更新數據發生錯誤 錯誤信息----%@", error.localizedDescription);
    }
}


// 通過username 獲取 User實體類
- (User *)getUserByUserName:(NSString *)username
{
    // User *user = [[User alloc] init];
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"User"];
    NSArray *array = [self.managerObjectContext executeFetchRequest:request error:nil];
    for (User *auser in array) {
        if ([auser.name isEqualToString:username]) {
            return auser;
       
        }
    }
    return nil;
}
 

關於NSPreidicate的拓展

NSPredicate用於查詢和過濾
在SQL中作為查詢條件通常用WHERE,但在COREDATA中作為查詢條件就可以用到NSPredicate.
NSPredicate 不單可以和COREDATA中的FetchRequest 配合使用。也可以與NSArray配合使用。
NSPredicate 中支持的關鍵詞和條件符:

1、>,<,>=,<=,= 比較運算符。


如:

NSPredicate * qcondition= [NSPredicate predicateWithFormat:@"salary >= 10000"];

2、字符串操作(包含):BEGINSWITH、ENDSWITH、CONTAINS


如:

@"employee.name BEGINSWITH[cd] '李'" //姓李的員工

@"employee.name ENDSWITH[c] '夢'" //以夢結束的員工

@"employee.name CONTAINS[d] '宗'" //包含有"宗"字的員工

注:[c]不區分大小寫[d]不區分發音符號即沒有重音符號[cd]既不區分大小寫,也不區分發音符號。

 

3、范圍:IN ,BWTEEN


如:

@"salary BWTEEN {5000,10000}"

@"em_dept IN '開發'"

 

4、自身:SELF,這個只針對字符數組起作用。


如:

NSArray * test = =[NSArray arrayWithObjects: @"guangzhou", @"beijing", @"shanghai", nil];

@"SELF='beijing'"

 

5、通配符:LIKE


LIKE 使用?表示一個字符,*表示多個字符,也可以與c、d 連用。

如:

@"car.name LIKE '?he?'" //四個字符中,中間為he

@"car.name LIKE '*jp'" //以jp結束
 

6、正則表達式:MATCHES


如:

NSString *regex = @"^E.+e$";//以E 開頭,以e 結尾的字符。
NSPredicate *pre= [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
if([pre evaluateWithObject: @"Employee"]){
NSLog(@"matches YES");

}else{
NSLog(@"matches NO");

}

7、邏輯運算符:AND、OR、NOT

如:

@"employee.name = 'john' AND employee.age = 28"

8、占位符:

NSPredicate *preTemplate = [NSPredicate predicateWithFormat:@"name==$NAME"];
NSDictionary *dic=[NSDictionary dictionaryWithObjectsAndKeys:
@"Name1", @"NAME",nil];
NSPredicate *pre=[preTemplate predicateWithSubstitutionVariables: dic];
占位符就是字典對象裡的key,因此你可以有多個占位符,只要key 不一樣就可以了。
 

 

 

CoreData的操作會轉換為SQL操作, 在Xcode上設置支持CoreData調試

Product-Scheme-Edit Scheme-Run-Arguments中依次添加兩個參數(注意參數順序不能錯):-com.apple.CoreData.SQLDebug1。然後在運行程序過程中如果操作了數據庫就會將SQL語句打印在輸出面板

 

\

 

 

最後注意:CoreData線程安全問題 和CoreData的版本遷移問題, 下次有時間再整理

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved