Как управлять отношениями с базами данных в объектах на iPhone с помощью Sqlite - PullRequest
0 голосов
/ 17 июня 2009

Например, если я могу отобразить UITableView со всеми фильмами и жанром. Нажатие «Редактировать» в фильме должно загрузить новое представление (это правильный путь, загрузка представления редактирования?) С текстовым полем и каким-либо селектором или другим видом для выбора жанра. После выбора жанра как записать GenreId для сохранения в таблице фильмов?

CREATE TABLE movie(pk INTEGER PRIMARY KEY, title TEXT, genreId INTEGER);

INSERT INTO make(title) VALUES('GoldFinger', 1);
INSERT INTO make(title) VALUES('Octopussy', 1);
INSERT INTO make(title) VALUES('Love Story', 3);
INSERT INTO make(title) VALUES('Where Eagles Dare', 1);
INSERT INTO make(title) VALUES('Zombies', 2);

CREATE TABLE genre(pk INTEGER PRIMARY KEY, title TEXT);

INSERT INTO genre(title) VALUES('Thriller');
INSERT INTO genre(title) VALUES('Horror');
INSERT INTO genre(title) VALUES('Romance');

Я использую образец Sqlitebooks в качестве руководства.

// Movie.h
@interface Movie : NSObject {
// Opaque reference to the underlying database.
sqlite3 *database;
// Primary key in the database.
NSInteger primaryKey;
// Attributes.
NSString *title;
NSInteger *genreKey;
// Internal state variables. Hydrated tracks whether attribute data is in the object or the database.
BOOL hydrated;
// Dirty tracks whether there are in-memory changes to data which have no been written to the database.
BOOL dirty;
NSData *data;
}
// Property exposure for primary key and other attributes. The primary key is 'assign'     because it is not an object,
// nonatomic because there is no need for concurrent access, and readonly because it     cannot be changed without
// corrupting the database.
@property (assign, nonatomic, readonly) NSInteger primaryKey;
// The remaining attributes are copied rather than retained because they are value     objects.
@property (copy, nonatomic) NSString *title;
@property (copy, nonatomic) NSInteger *genreKey;
// Finalize (delete) all of the SQLite compiled queries.
+ (void)finalizeStatements;
// Creates the object with primary key and title is brought into memory.
- (id)initWithPrimaryKey:(NSInteger)pk database:(sqlite3 *)db;
// Inserts the book into the database and stores its primary key.
- (void)insertIntoDatabase:(sqlite3 *)database;
// Brings the rest of the object data into memory. If already in memory, no action is     taken (harmless no-op).
- (void)hydrate;
// Flushes all but the primary key and title out to the database.
- (void)dehydrate;
// Remove the book complete from the database. In memory deletion to follow...
- (void)deleteFromDatabase;

// Movie.m
// Flushes all but the primary key and title out to the database.
- (void)dehydrate {
    if (dirty) {
    // Write any changes to the database.
    // First, if needed, compile the dehydrate query.
    if (dehydrate_statement == nil) {
        const char *sql = "UPDATE movie SET title=?, genreid=? WHERE pk=?";
        if (sqlite3_prepare_v2(database, sql, -1, &dehydrate_statement, NULL) != SQLITE_OK) {
            NSAssert1(0, @"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
        }
    }
    // Bind the query variables.
    sqlite3_bind_text(dehydrate_statement, 1, [title UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_text(dehydrate_statement, 2, [genreId UTF8String], -1, SQLITE_TRANSIENT);
    sqlite3_bind_int(dehydrate_statement, 3, primaryKey);
    // Execute the query.
    int success = sqlite3_step(dehydrate_statement);
    // Reset the query for the next use.
    sqlite3_reset(dehydrate_statement);
    // Handle errors.
    if (success != SQLITE_DONE) {
        NSAssert1(0, @"Error: failed to dehydrate with message '%s'.", sqlite3_errmsg(database));
    }
    // Update the object state with respect to unwritten changes.
    dirty = NO;
}
// Release member variables to reclaim memory. Set to nil to avoid over-releasing them 
// if dehydrate is called multiple times.
[movie release];
movie = nil;
[data release];
data = nil;
// Update the object state with respect to hydration.
hydrated = NO;
}
@end

1 Ответ

2 голосов
/ 17 июня 2009

Это не дает прямого ответа на ваш вопрос, однако я бы посоветовал взглянуть на новые API CoreData, добавленные в 3.0 SDK. Они позволят вам смоделировать ваши реляционные данные и абстрагироваться от любой ручной работы с SQL, что позволит сократить объем кода и, если все сделано правильно, повысить производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...