iOS開發之數據存儲之Core Data

1、概述數據庫

Core Data框架提供了對象-關係映射(ORM)的功能,即可以將OC對象轉化成數據,保存在SQLite3數據庫文件中,也可以將保存在數據庫中的數據還原成OC對象。在此數據操做期間,不須要編寫任何SQL語句。使用此功能,要添加CoreData.framework和導入主頭文件<CoreData/CoreData.h>。app

2、模型文件框架

在Core Data,須要進行映射的對象稱爲實體(entity),並且須要使用Core Data的模型文件來描述應用的全部實體和實體屬性。性能

這裏以Person和Card(身份證)2個實體爲例子,先看看實體屬性和之間的關聯關係。url

Person中有個Card屬性,Card中有個Person屬性。日誌

屬於一對一雙向關聯。orm

使用方法:對象

建立文件:排序

添加實體:ip

添加Person實體的基本屬性:

添加Card實體的基本屬性:

在Person中添加card屬性:

在Card中添加person屬性:

3NSManagedObject

經過Core Data從數據庫取出的對象,默認狀況下都是NSManagedObject對象,NSManagedObject的工做模式有點相似於NSDictionary對象,經過鍵-值對來存取全部的實體屬性。

(1)setValue:forKey: 存儲屬性值(屬性名爲key)

(2)valueForKey: 獲取屬性值(屬性名爲key)

4Core Data主要對象

 

5、搭建Core Data上下文環境

從應用程序包中加載模型文件:

NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];

 

傳入模型,初始化NSPersistentStoreCoordinator:

NSPersistentStoreCoordinator *psc = [[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model] autorelease];

 

構建SQLite文件路徑:

NSString *docs =

[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

 

NSURL *url = [NSURL fileURLWithPath:[docs stringByAppendingPathComponent:@"person.data"]];

 

添加持久化存儲庫,這裏使用SQLite做爲存儲庫:

NSError *error = nil;

NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error];

if (store == nil) { // 直接拋異常

    [NSException raise:@"添加數據庫錯誤" format:@"%@", [error localizedDescription]];

}

 

初始化上下文,設置persistentStoreCoordinator屬性:

NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];

context.persistentStoreCoordinator = psc;

// 用完以後,仍是要[context release];

【備註】持久化存儲庫的類型:

  • NSSQLiteStoreType  SQLite數據庫
  • NSBinaryStoreType  二進制平面文件
  • NSInMemoryStoreType 內存庫,沒法永久保存數據

雖然這3種類型的性能從速度上來講都差很少,但從數據模型中保留下來的信息卻不同。

在幾乎全部的情景中,都應該採用默認設置,使用SQLite做爲持久化存儲庫

6、添加數據

傳入上下文,建立一個Person實體對象:

NSManagedObject *person =

[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];

 

設置簡單屬性:

[person setValue:@"MJ" forKey:@"name"];

[person setValue:[NSNumber numberWithInt:27] forKey:@"age"];

 

傳入上下文,建立一個Card實體對象:

NSManagedObject *card = [NSEntityDescription insertNewObjectForEntityForName:@"Card" inManagedObjectContext:context];

[card setValue:@"4414241933432" forKey:@"no"];

 

設置Person和Card之間的關聯關係:

[person setValue:card forKey:@"card"];

 

利用上下文對象,將數據同步到持久化存儲庫:

NSError *error = nil;

BOOL success = [context save:&error];

if (!success) {

    [NSException raise:@"訪問數據庫錯誤" format:@"%@", [error localizedDescription]];

}

// 若是是想作更新操做:只要在更改了實體對象的屬性後調用[context save:&error],就能將更改的數據同步到數據庫

7、查詢數據

初始化一個查詢請求:

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];

 

設置要查詢的實體:

NSEntityDescription *desc = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context];

 

設置排序(按照age降序):

NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"age" ascending:NO];

request.sortDescriptors = [NSArray arrayWithObject:sort];

 

設置條件過濾(name like '%Itcast-1%'):

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@", @"*Itcast-1*"];

request.predicate = predicate;

【備註】設置條件過濾時,數據庫裏面的%要用*來代替

 

執行請求:

NSError *error = nil;

NSArray *objs = [context executeFetchRequest:request error:&error];

if (error) {

    [NSException raise:@"查詢錯誤" format:@"%@", [error localizedDescription]];

}

 

遍歷數據:

for (NSManagedObject *obj in objs) {

    NSLog(@"name=%@", [obj valueForKey:@"name"]

}

8、刪除數據

傳入須要刪除的實體對象:

[context deleteObject:managedObject];

 

將結果同步到數據庫:

NSError *error = nil;

[context save:&error];

if (error) {

    [NSException raise:@"刪除錯誤" format:@"%@", [error localizedDescription]];

}

9、打開Core DataSQL日誌輸出開關

1.打開Product,點擊Edit Scheme...

2.點擊Arguments,在Arguments Passed On Launch中添加2項

  • -com.apple.CoreData.SQLDebug
  • 1
  • 10Core Data的延遲加載

    Core Data不會根據實體中的關聯關係當即獲取相應的關聯對象,好比經過Core Data取出Person實體時,並不會當即查詢相關聯的Card實體;當應用真的須要使用Card時,纔會查詢數據庫,加載Card實體的信息。

    十一、    建立NSManagedObject的子類

    默認狀況下,利用Core Data取出的實體都是NSManagedObject類型的,可以利用鍵-值對來存取數據,可是通常狀況下,實體在存取數據的基礎上,有時還須要添加一些業務方法來完成一些其餘任務,那麼就必須建立NSManagedObject的子類。

  • 選擇模型文件:

  • 選擇須要建立子類的實體:

  • Person.h – Person.m

    Card.h – Card.m

  • 那麼生成一個Person實體對象就應該這樣寫:

    Person *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];

    person.name = @"MJ";

    person.age = [NSNumber numberWithInt:27];

    Card *card = [NSEntityDescription insertNewObjectForEntityForName:@」Card" inManagedObjectContext:context];

    card.no = @」4414245465656";

    person.card = card;

相關文章
相關標籤/搜索