[iPhone SDK] sqlite 学習中。FMDB を知る。

公開日: : 最終更新日:2011/11/13 iPad, iPhone ,

SQLite入門 第2版
SQLite入門 第2版 西沢 直木

翔泳社 2009-05-19
売り上げランキング : 175821

Amazonで詳しく見る by G-Tools

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
iPhone Advanced Projects
Apress 2009-11-04
売り上げランキング : 74266

Amazonで詳しく見る by G-Tools

関連記事

no image

iPad アプリの iOS Deployment Target に設定するバージョン値を検討する

自作アプリのiPadの対応バージョンを決める際に、一番古くから対応していることにした場合どのバージ

記事を読む

no image

さくらのVPSにRedmine+Subversionを入れてみた

一応個人ソースコード管理にはAssemblaを使っていたが、いつ有料になるか分からないし自分でサーバ

記事を読む

Apple Special Event September 2018

今年も新型iPhoneを発表するアップルのスペシャルイベントが2018年9月13日2時AM(12日1

記事を読む

Topeak iPhone6 Plus 用ライドケースセットを買ってみた

家から最寄り駅まで歩くと結構時間がかかってしまうため、駅前に駐輪場を借りてそこまで自転車で通勤してい

記事を読む

EverLearn-Pebble

2016年の総括

2015年の振り返り を振り返ってみて興味深かったので、2016年も書いてみる。個人的には、2016

記事を読む

no image

MacPeople 2012 5月号にはほしいガジェットがたくさん紹介されてる

定期購読しているMacPeopleの今月号(5月号)で面白い製品がたくさん紹介されていたのでメモを書

記事を読む

no image

UIScrollView の上で UIView を動かしたい

今作っているiPadアプリで、画面をピンチインアウトで拡大縮小して、さらにその上でドラッグで部品を動

記事を読む

[iOS SDK] EverLearn 3Dタッチ対応

iPhone 7 Plus を購入したので、まずは EverLearn から、3Dタッチの対応を行い

記事を読む

iOS用アイコンをまとめて生成する

しばらく開発してきたアプリがようやくリリースできる状態になってきたので、知り合いのデザイナーと飲み

記事を読む

no image

iPhone/iPad で教育

この本は面白そう。今後は教育分野での応用も増えていくだろう。 その時に、iPhone/iPad は教

記事を読む

Message

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

ポモドーロテクニック用物理タイマーならTime Timer

会社ではなかなか自由に時間を使えないが、家で読書や作業をする

DELL 32インチディスプレイ U3223QE 購入

Dell U3223QE は解像度 3840x216

WWDC 2023 Vision Pro発表

2023/6/5 (日本時間 2023/06/06 2AM)のWWD

M1 MacBook Air を Venturaにアップデートする

M1 MacBook Air を macOS Montere

iOS16でaurioTouch の inBufferFramesが1になる

https://developer.apple.com/librar

→もっと見る

PAGE TOP ↑