今回作成したサンプルは、都道府県データベースアプリケーションです。
都道府県名を変更すると、県庁所在地と郷土料理が切り替わります。都道府県名も県庁所在地も郷土料理名もすべてデータベースから取得しています。データベースのスキーマは以下のようになっています。
県庁所在地は各都道府県に必ず1つだけ存在するので、プライマリキーを設定しています。郷土料理はいくつ存在するか分からないため、プライマリキーはありません。この2つのテーブルは都道府県でリレーションしています。
なお、郷土料理が登録されていない県がありますが、あしからずご了承ください。
スキーマが決まったら、データベースを作成します。
データベースの作成方法はいろいろありますが、今回は「SQLiteOpenHelper」というクラスを利用します。このクラスは、abstract(抽象)クラスなので、以下のコールバックを実装する必要があります。
データベースの存在チェックやテーブルの作成、初期データの追加、データベースのバージョンアップ時の処理などが、このクラスを使用することで分離できるので、SQLiteDatabaseクラスでデータベースを直接作成するよりも便利だと思います。
テーブルにレコードを追加する場合、通常は1レコードずつ追加しなければなりません。これを素直に実装すると、以下のようになります。
for (String s : array) { db.execSQL(“insert into table values (‘” + s + “’);”); }
1レコードを追加する場合であれば、この方法で十分ですが、複数レコードを追加するのであれば、以下のようにトランザクションとプリコンパイルステートメントを使うことを推奨します。
db.beginTransaction(); try { SQLiteStatement stmt = db.compileStatement("insert into table values (?);"); for (String s : array) { stmt.bindString(1, s); stmt.executeInsert(); } db.setTransactionSuccessful(); } finally { db.endTransaction(); }
このコードは前述のexecSQLを単体で実行するのに比べ、以下のメリットがあります。
上記のコードでは、tryブロックの最後のSQLiteDatabase#setTransactionSuccessful()を呼び出すと、データベースへの変更がコミットされ、呼び出さなければロールバックされます。「例外が発生したらロールバックする」という実装ですね。
処理速度にどれぐらいの差異があるのか計ってみました。以下は、今回のサンプルアプリケーションで約190レコードを追加する際にかかった時間です。
SQLiteDatabase#execSQL(String) | トランザクション+SQLiteStatement | |
---|---|---|
1回目 | 871ms | 462ms |
2回目 | 925ms | 488ms |
3回目 | 860ms | 540ms |
4回目 | 1111ms | 510ms |
5回目 | 948ms | 498ms |
平均 | 943ms | 500ms |
表1 処理速度の比較 |
トランザクション+SQLiteStatemenの方がおよそ半分の時間で済んでいます。レコード数が増えれば増えるほど、この差はどんどん大きくなります。
SQLiteはクライアント・サーバ型のデータベースとは異なり、アプリケーションに組み込んで使用するようにデザインされています。AndroidのSQLiteの場合、データベースはデータベースを作成したアプリケーション専用です。
さらにAndroidの場合、データベースの作成場所をストレージにするか、メモリにするかを選択できます。今回のデモアプリはデータが少ないので、メモリ上にデータベースを作成しています。
ストレージに作成するかメモリに作成するかは、DatabaseHelperクラスのコンストラクタの第2引数で指定します。
public DatabaseHelper(Context context) { super(context, null, null, 1); }
ここがnullならメモリ上に、ファイル名を指定した場合は「/data/data/<パッケージ名>/database/<ファイル名>」に、という具合にデータベースファイルが作成されます。指定するのはファイル名だけなので、間違えないようにしてください。
ファイル名を指定した場合は、2回目以降の起動でデータベースがすでに存在する可能性があるのですが、もし存在するならDatabaseHelper#onCreate(SQLiteDatabase)メソッドは呼び出されません。DatabaseHelperを使用すれば、データベースの存在チェックを行わなくてもよいわけです。本当に便利です。
次ページでは、データベースを削除する際の注意点やデータ検索の仕方の基本を解説します。
Copyright © ITmedia, Inc. All Rights Reserved.