閱讀644 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Core Data淺談係列之九 : 使用Mapping Model

通常,我們都會盡量使數據模型的變化盡量簡單。但有些情況下,不得不進行大的改動,甚至是重新設計數據模型。在這種情況下,之前提過的簡單數據遷移已經無法適應了,需要引入Mapping Model這個中間層。
這時,又想起之前提過的一句話:

There is no problem in computer science that can’t be solved by adding another level of indirection.

這裏做一個簡單的變動,先為球員增加薪水屬性: 



然後創建一名球員,信息如下:



這時候我們打算為球員調薪,比如上漲10%。為了結合NSMappingModel,這裏簡單地增加了一個新的屬性newSalary,並且希望在數據遷移時更新該屬性。為此,我們創建了一個NSMappingModel映射模型:







選擇好源數據模型和目標數據模型,設置newSalary和salary的關係:



這表示目標屬性newSalary的值為源屬性salary的1.1倍。

這個時候,我們不希望Core Data自動為我們映射模型,所以修改一下遷移選項: 
     NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
     [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
     [NSNumber numberWithBool:NO], NSInferMappingModelAutomaticallyOption, nil];
把NSInferMappingModelAutomaticallyOption設置為NO後,我們需要手工指定映射模型:
        NSString *mappingModelPath = [[NSBundle mainBundle] pathForResource:@"mappingModel3to4" ofType:@"cdm"];
        NSURL *mappingModelUrl = [NSURL fileURLWithPath:mappingModelPath];
        NSMappingModel *mappingModel = [[[NSMappingModel alloc] initWithContentsOfURL:mappingModelUrl] autorelease];
接著,進行實質性的數據遷移。簡單起見,這裏就沒有做錯誤檢查了:
        NSMigrationManager *migrationManager = [[[NSMigrationManager alloc] initWithSourceModel:sourceModel destinationModel:destinationModel] autorelease];

        if (![migrationManager migrateStoreFromURL:storeURL type:NSSQLiteStoreType options:nil withMappingModel:mappingModel  toDestinationURL:tmpStoreURL destinationType:NSSQLiteStoreType destinationOptions:nil error:&error]) {
            NSLog(@"Error migrating %@, %@", error, [error userInfo]);
            abort();
        }

        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSString *oldStoreName = @"cdNBA_old.sqlite";
        NSURL *oldStoreURL = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:oldStoreName]];
        [fileManager moveItemAtURL:storeURL toURL:oldStoreURL error:&error];
        [fileManager moveItemAtURL:tmpStoreURL toURL:storeURL error:&error];
再跑一遍Demo,然後在終端裏查看:



可以發現有一份舊的sqlite文件和一份新的。
通過查看新的sqlite文件中的數據,可以得知newSalary的值: 



其中,newSalary為2420000.0,剛好是salary的值2200000.0的1.1倍。

Brief Talk About Core Data Series, Part 9 : Using Mapping Model 

Jason Lee @ Hangzhou

最後更新:2017-04-04 07:03:41

  上一篇:go Mac OS X ft_rich遊戲的進一步更改
  下一篇:go IOS開發網站匯總