[iPhone SDK] sqlite 学習中。FMDB を知る。
| SQLite入門 第2版 | |
![]() |
西沢 直木
翔泳社 2009-05-19 |
Head First SQLでせっかくSQLを学習したので、何かiPhoneアプリを作ってみようと思う。
これまではデータ保存はもっぱら NSCoder APIだったが、今回はSQLを使ってデータベースに保存してみることにする。
。
iPhoneでデータベースを使いたい場合、sqlite か Core Data を選択することになると思うが、Core Data はある程度大規模なデータベースを対象にしたものだと思われ、敷居が高い。
自分の用途だとCore Data までは不要だと思われるし、まだドキュメントが少ない。ということで、軽量で取り扱いが容易そうな sqlite を使うことにする。
で、手持ちのiPhone開発本でsqliteを使っているものを探してみたら、はじめてのiPhone3プログラミングとiPhone Advanced Projectsがあった。意外にsqliteを解説した本はない。
実は、sqliteはApple自身もあまり解説していないようだし、そもそもAPIがCでなかなか使いづらい。
。
AppleはiPhone OS 3でCore Dataをサポートし、今後はこちらをおしていこうとしていると思われるので、この状況が改善されることは無さそうだ。
で、sqliteをそのまま使うのはつらいことが分かってきたので調べていると、どうやら FMDB を使うのがよいらしい。(2010年7月に github に移動した模様。ccgus fmdb )
FMDBはいわゆるドキュメントがなく、サンプルコードをみて理解してください、というスタンスらしい。サンプルコードは fmdb.m になる。
(と思ったが、ccgus fmdb をよく見るとreadme.markdown で使い方が説明されていた。結構わかりやすい。これを見ればこのページの内容は不要だった気がする 2011/11/12 追記)
そしてそのFMDB を日本語で解説しているページもあまりないが、プログラミングノート さんがわかりやすい。このサイトで Lita を初めて知った。
ちなみに、FMDB のようなものを自作したいと思ったら、iPhone Advanced Projects の第5章、Stick Around: Building Data-Driven Applications with SQLite がおすすめ。
かなり詳細に、sqlite のObjective-Cラッパークラスの作り方と、得られた結果のオブジェクトモデルへのマップ方法が書かれている。
よく見ると著者は AppViz の人だった。
組み込み方は簡単で、FMDatabase.h/m, FMDatabaseAdditions.h/m, FMResultSet.h/m をプロジェクトにコピーして、既存のフレームワーク として、libsqlite3.dylib を組み込む。libsqlite3.0.dylib もあるけれども何が違うのかは不明。
サンプルプログラムから CREATE TABLE を抜き出してみると、Table は下記のものを作っている。
text, integer, double, blob があるようだ。
[db executeUpdate:@"create table test (a text, b text, c integer, d double, e double)"]; [db executeUpdate:@"create table blobTable (a text, b blob)"]; [db executeUpdate:@"create table t1 (a integer)"]; [db executeUpdate:@"create table t2 (a integer, b integer)"]; [db executeUpdate:@"create table t3 (a somevalue)"]; [db executeUpdate:@"create table nulltest (a text, b text)"]; [db executeUpdate:@"create table datetest (a double, b double, c double)"]; [db executeUpdate:@"create table nulltest2 (s text, d data, i integer, f double, b integer)"]; [db executeUpdate:@"create table testOneHundredTwelvePointTwo (a text, b integer)"];
データの格納はこんな感じ。
doubleなどを格納するときは NSNumberにする必要がある。忘れるといきなり落ちるのではまる。
[db executeUpdate:@"insert into test (a, b, c, d, e) values (?, ?, ?, ?, ?)" ,
@"hi'", // look! I put in a ', and I'm not escaping it!
[NSString stringWithFormat:@"number %d", i],
[NSNumber numberWithInt:i],
[NSDate date],
[NSNumber numberWithFloat:2.2f]];
[db executeUpdate:@"insert into blobTable (a, b) values (?,?)", @"safari's compass", safariCompass];
[db executeUpdate:@"insert into t1 values (?)", [NSNumber numberWithInt:5]];
[db executeUpdate:@"insert into nulltest (a, b) values (?, ?)" , [NSNull null], @"a"];
[db executeUpdate:@"insert into nulltest (a, b) values (?, ?)" , nil, @"b"];
[db executeUpdate:@"insert into datetest (a, b, c) values (?, ?, 0)" , [NSNull null], date];
[db executeUpdate:@"insert into nulltest2 (s, d, i, f, b) values (?, ?, ?, ?, ?)" , @"Hi", safariCompass, [NSNumber numberWithInt:12], [NSNumber numberWithFloat:4.4], [NSNumber numberWithBool:YES]];
[db executeUpdate:@"insert into nulltest2 (s, d, i, f, b) values (?, ?, ?, ?, ?)" , nil, nil, nil, nil, [NSNull null]];
[db executeUpdate:@"insert into testOneHundredTwelvePointTwo values (?, ?)" withArgumentsInArray:[NSArray arrayWithObjects:@"one", [NSNumber numberWithInteger:2], nil]];
クエリはこちら。
FMResultSet *rs = [db executeQuery:@"select rowid,* from test where a = ?", @"hi'"]; rs = [db executeQuery:@"select b from blobTable where a = ?", @"safari's compass"]; int a = [db intForQuery:@"select a from t1 where a = ?", [NSNumber numberWithInt:5]]; rs = [newDb executeQuery:@"select rowid,* from test where a = ?", @"hi'"]; rs = [db executeQuery:@"select * from t2"]; FMResultSet *rs2 = [db executeQuery:@"select a from t3 where a = ?", [NSNumber numberWithInt:newVal]]; rs = [db executeQuery:@"select * from nulltest"]; NSDate *foo = [db dateForQuery:@"select b from datetest where c = 0"]; rs = [db executeQuery:@"select * from testOneHundredTwelvePointTwo where b > ?" withArgumentsInArray:[NSArray arrayWithObject:[NSNumber numberWithInteger:1]]]; rs = [db executeQuery:@"select t4.a as 't4.a', t4.b from t4;"]; rs = [db executeQuery:@"select t4.a as 't4.a', t4.b from t4;" withArgumentsInArray:[NSArray array]];
データを取り出すときには、intForColumn, longForColumn, stringForColumn, dateForColumn, doubleForColumn, dataForColumn で格納されているデータにより使い分けて取り出す。
xxxForColumn:カラム名 の他に、xxxForColumnIndex:インデックス番号 も使うことができる。
インデックス0はrowidなので、最初のインデックスは1になる。
FMResultSet *rs = [db executeQuery:@"select rowid,* from test where a = ?", @"hi'"];
while ([rs next]) {
// just print out what we've got in a number of formats.
NSLog(@"%d %@ %@ %@ %@ %f %f",
[rs intForColumn:@"c"],
[rs stringForColumn:@"b"],
[rs stringForColumn:@"a"],
[rs stringForColumn:@"rowid"],
[rs dateForColumn:@"d"],
[rs doubleForColumn:@"d"],
[rs doubleForColumn:@"e"]);
}
sqlite をそのまま使うよりかなり楽なのではないかと。
参考書は、SQLite入門 第2版 がわかりやすくて良かった。
| iPhone Advanced Projects | |
![]() |
Apress 2009-11-04 売り上げランキング : 74266 by G-Tools |
関連記事
-
-
薄い iPad2用ケース eggshell for iPad2 TUN-PD-000079 購入 2011/06/27
不具合報告があったので、当初予定がなかったiPad2を購入。 それはまた別に書くとして、まずは一緒に
-
-
[Apple Watch] 2017年の冬休みの宿題はwatchOSアプリ開発
自分はPebble初代のころからスマートウォッチはPebble派だったが、2016年の年末は Peb
-
-
[iPhone SDK] ネットワーク接続の有無を確認する方法
iPhoneでネットワーク接続できないときには一応エラーダイアログを出す方がよいだろうと考えて方法を
-
-
iPhone 16 Pro Max 購入
iPhone 16 Pro Max 256GB 189000円で2024/11/8に Ap
-
-
MacPeople 2010.02
定期購読している MacPeople 2010年2月号が今日届いた。 今回はメールアプリとUbunt
-
-
4年ぶりにLogLocationsをアップデート
4年ぶりにLogLocationsのアップデート版を作成中。3年間更新していなかったので、画面がフラ
-
-
英単語学習アプリ EverLearn 1.4.0 を公開しました
ようやく、iOS7 に対応した EverLearn 1.4.0 を公開しました。 i
-
-
2歳の娘がiPadを離しません タッチ! うごく うたえほん
開発用に買ったのでアプリ開発時以外はあまり使っていなかったiPadはここしばらく完全に2歳の娘用にな
-
-
iPhone 4S は Bluetooth 4.0 採用。G-SHOCK GB-6900 が使えるとよいのだが
アップル - iPhone - 比較 によると確かに iPhone 4S から Bluetooth
-
-
iPhone SDK開発のネタ帳 マルチタッチ対応
iPhone SDK開発のレシピにはいろいろ役に立つ内容があったので、同じようなことをブログに書いて

