현재 다양한 데이터를 수정하고 유지해야하는 응용 프로그램을 작성 중입니다. 이 목적으로 핵심 데이터를 사용하기로 결정했습니다. 사용자가 처음으로 응용 프로그램을 열면 sqlite 데이터베이스에서 많은 양의 데이터를 가져와야합니다.이 데이터는 다 대다 관계로 구성됩니다.SQLite 데이터베이스의 핵심 데이터 "Upsert"
모든 데이터를 코드 데이터 저장소에 삽입하는 가장 좋은 방법을 찾고 싶습니다. 지금은 NSOperation을 사용하여 나머지 응용 프로그램을 활성 상태로 유지하면서 사용자가 다른 작업을 수행 할 수 있도록 가져 오기를 수행하지만 최대한 빨리 가져 오기를 수행하여 전체 App에 즉시 액세스 할 수있게하고 싶습니다. .
내가 지금 사용하고있는 방법은 NSFetchRequest를 사용하여 데이터 저장소에서 관련된 엔티티를 찾으려고 시도합니다. 엔티티가 있으면 거기에 엔티티가 추가됩니다. 엔티티가 없으면 만들면됩니다. 새로운 것을 추가하고 관계로 추가하십시오. 이것은 효과가 있지만, 아마도 그것이 최적에 근접하지는 않을 것이라고 생각합니다.
코드 지금 사용하고 있습니다 :
- (void)importEntitiesIntoContext: (NSManagedObjectContext*)managedObjectContext
{
// Setup the database object
static NSString* const databaseName = @"DBName.sqlite";
NSString* databasePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: databaseName];
sqlite3* database;
// Open the database from the user's filessytem
if (sqlite3_open_v2([databasePath UTF8String], &database, SQLITE_OPEN_READONLY, NULL) == SQLITE_OK)
{
// Setup the SQL Statement
NSString* sqlStatement = [NSString stringWithFormat: @"SELECT some_columns FROM SomeTable;"];
sqlite3_stmt* compiledStatement;
if (sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK)
{
// Create objects to test for existence of exercises
NSPredicate* predicate = [NSPredicate predicateWithFormat: @"something == $SOME_NAME"];
NSEntityDescription* entityDescription = [NSEntityDescription entityForName: @"SomeEntity"
inManagedObjectContext: managedObjectContext];
NSFetchRequest* fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setEntity: entityDescription];
// Loop through the results and add them to the feeds array
while (sqlite3_step(compiledStatement) == SQLITE_ROW)
{
NSString* someName = [NSString stringWithCharsIfNotNull: (char*)sqlite3_column_text(compiledStatement, 1)];
NSPredicate* localPredicate = [predicate predicateWithSubstitutionVariables:
[NSDictionary dictionaryWithObject: someName
forKey: @"SOME_NAME"]];
[fetchRequest setPredicate: localPredicate];
NSError* fetchError;
NSArray* array = [managedObjectContext executeFetchRequest: fetchRequest
error: &fetchError];
if (array == nil)
{
// handle error
}
else if ([array count] == 0)
{
SomeEntity* entity =
[NSEntityDescription insertNewObjectForEntityForName: @"SomeEntity"
inManagedObjectContext: managedObjectContext];
entity.name = someName;
// **here I call a method that attempts to add the relationships(listed below)**
}
else
{
// Some entity already in store
}
}
}
else
{
NSLog(@"sqlStatement failed: %@", sqlStatement);
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
// All the data has been imported into this temporary context, now save it
NSError *error = nil;
if (![managedObjectContext save: &error])
{
NSLog(@"Unable to save %@ - %@", [error localizedDescription]);
}
}
방법을 관계 추가 :
- (void)setRelationshipForEntity: (Entity*)entity
inManagedObjectContext: (NSManagedObjectContext*)managedObjectContext
usingDatabase: (sqlite3*)database
entityId: (NSNumber*)entityId
{
// Setup the SQL Statement and compile it for faster access
NSString* sqlStatement = [NSString stringWithFormat: @"SELECT Relationship.name FROM Relationship JOIN Entitys_Relationship ON Entitys_Relationship.id_Relationship = Relationship.id JOIN Entitys ON Entitys_Relationship.id_Entitys = Entitys.id WHERE Entitys.id = %d;", [entityId integerValue]];
sqlite3_stmt* compiledStatement;
if (sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK)
{
// Create objects to test for existence of relationship
NSPredicate* predicate = [NSPredicate predicateWithFormat: @"relationshipName == $RELATIONSHIP_NAME"];
NSEntityDescription* entityDescription = [NSEntityDescription entityForName: @"EntityRelationship"
inManagedObjectContext: managedObjectContext];
NSFetchRequest* fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setEntity: entityDescription];
while (sqlite3_step(compiledStatement) == SQLITE_ROW)
{
NSString* relationshipName = [NSString stringWithCharsIfNotNull: (char*)sqlite3_column_text(compiledStatement, 0)];
NSPredicate* localPredicate = [predicate predicateWithSubstitutionVariables:
[NSDictionary dictionaryWithObject: relationshipName
forKey: @"RELATIONSHIP_NAME"]];
[fetchRequest setPredicate: localPredicate];
NSError* fetchError;
NSArray* array = [managedObjectContext executeFetchRequest: fetchRequest
error: &fetchError];
if (array == nil)
{
// handle error
}
else if ([array count] == 0)
{
EntityRelationship* entityRelationship =
[NSEntityDescription insertNewObjectForEntityForName: @"EntityRelationship"
inManagedObjectContext: managedObjectContext];
entityRelationship.relationshipName = relationshipName;
[entity addRelationshipObject: entityRelationship];
//NSLog(@"Inserted relationship named %@", relationshipName);
}
else
{
[entity addRelationship: [NSSet setWithArray: array]];
}
}
}
else
{
NSLog(@"slqStatement failed: %@", sqlStatement);
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
정보가 sqlite 데이터베이스에 있으면 사용자는 개인 장치의 정보를 변경할 수 있지만 App 업데이트의 경우 데이터를 새 데이터와 병합해야합니다. – jessecurry
병합을 장치의 사용자 코어 데이터 저장소와 응용 프로그램의 업데이트 된 초기 코어 데이터 저장소간에 병합하도록 했으므로 핵심 데이터 작업을 선호하기 때문입니다. – gerry3
초기 CoreData 저장소를 만드는 데 일반적으로 어떤 방법을 사용합니까? – jessecurry