ページ

2010年5月20日木曜日

CoreData - リレーションシップ(4) タグを使った検索

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

(前回)Cocoaの日々: CoreData - リレーションシップ(3) 多対多のモデリング

今回はタグを使った検索を行ってみる。といってもエントリの検索と全く同じ。

- (void)fetchDataByTag
{
NSManagedObjectContext* moc = [self managedObjectContext];
NSFetchRequest* request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Tag"
inManagedObjectContext:managedObjectContext]];
NSError* error = nil;
NSLog(@"----- executeFetchRequest ------------------------------------------");
NSArray* tags = [moc executeFetchRequest:request error:&error];
NSLog(@"----- listup entry ---------------------------------------------------");
for (Tag* tag in tags) {
NSLog(@"tag name=%@", tag.name);
for (BlogEntry* entry in tag.entries) {
NSLog(@"*entry*: %@", entry.title);
}
}
[request release];
}


結果
[16229:10b] ----- executeFetchRequest ------------------------------------------
[16229:10b] ----- listup entry ---------------------------------------------------
[16229:10b] tag name=Mac
[16229:10b] *entry*: CoreData のリレーションしっぷについて
[16229:10b] tag name=iPad
[16229:10b] *entry*: iPad 5/28発売
[16229:10b] *entry*: CoreData のリレーションしっぷについて
[16229:10b] tag name=iPhone
[16229:10b] *entry*: CoreData のリレーションしっぷについて

発行している SQLをチェックしてみる。

[16245:10b] CoreData: sql: pragma cache_size=1000
16245:10b] ----- executeFetchRequest ------------------------------------------
[16245:10b] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZNAME FROM ZTAG t0
[16245:10b] CoreData: annotation: sql connection fetch time: 0.0682s
[16245:10b] CoreData: annotation: total fetch execution time: 0.0752s for 3 rows.
[16245:10b] ----- listup entry ---------------------------------------------------
[16245:10b] tag name=Mac
[16245:10b] CoreData: sql: SELECT 0, t0.Z_PK FROM Z_1TAGS t1 JOIN ZBLOGENTRY t0 ON t0.Z_PK = t1.Z_1ENTRIES WHERE t1.Z_2TAGS = ? ...(1)
[16245:10b] CoreData: annotation: sql connection fetch time: 0.0054s
[16245:10b] CoreData: annotation: total fetch execution time: 0.0102s for 1 rows.
[16245:10b] CoreData: annotation: to-many relationship fault "entries" for objectID 0x1715a0 <x-coredata://C7F5193B-3731-4955-8F11-51453ABAAC99/Tag/p1> fulfilled from database.  Got 1 rows ...(2)
[16245:10b] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZTITLE, t0.ZCONTENT, t0.ZCREATED FROM ZBLOGENTRY t0 WHERE  t0.Z_PK = ? ...(3)
[16245:10b] CoreData: annotation: sql connection fetch time: 0.0043s
[16245:10b] CoreData: annotation: total fetch execution time: 0.0079s for 1 rows.
[16245:10b] CoreData: annotation: fault fulfilled from database for : 0x173270 <x-coredata://C7F5193B-3731-4955-8F11-51453ABAAC99/BlogEntry/p2>[16245:10b] *entry*: CoreData のリレーションしっぷについて
 :
 :

ポイントとなる箇所の色を変えてある。

(1) まず中間テーブル Z_1TAGS からエントリのプライマリキーにあたるカラム値(Z_PK)を取得する。
(2) 続いて、Z_PKに対応するオブジェクトの状態が fault なので、DBへフェッチしにいく。
(3) (1)で取得した Z_PK(複数)の値を条件に ZBLOGENTRY からデータを取得し有効な BlogEntry のインスタンスを用意する。


ソース:
CoreDataRelationship at 2010-05-20 from xcatsan's SampleCode - GitHub

- - - -
RDB しか経験が無いので、ついつい SQLite のスキーマを確認してしまった。ただそのおかげで徐々にモデリングのイメージがつかめてきた。