まずは、データの挿入について説明する。“name_book_table”テーブルにデータを1件追加するための処理は、以下のように記述する。
/** エントリ追加 */ private void doAddEntry( SQLiteDatabase db, String name, int age ){ // 挿入するデータはContentValuesに格納 ContentValues val = new ContentValues(); val.put( "name", name ); val.put( "age" , age ); // “name_book_table”に1件追加 db.insert( "name_book_table", null, val ); }
データの挿入には、SQLiteDatabaseクラスのinsert()メソッドを使用する。第1引数にはテーブル名を指定し、第2引数には取りあえずnullを指定する。第3引数は実際に挿入するデータの指定となるが、これはあらかじめContentValuesというデータクラスに格納した状態で渡す。
これ以外にも、テーブル定義作成の時に使ったexecSQL()メソッドを使用する方法もある。
db.execSQL( "insert into name_book_table(name,age) values( 'Tips太郎', 30 )" );
ただ、insert()メソッドが挿入成功件数を返すのに対し、execSQL()メソッドは値を返さないという違いがある。そのため、基本的にはinsert()メソッドを使った方がよさそうだ。
次に、データの検索について。検索は、SQLiteDatabaseのquery()メソッドを使用する。検索結果は、Cursorオブジェクトとして返されるのだが、このCursorオブジェクトから具体的な検索結果を取り出すところが少し複雑だ。
以下に、検索処理の例を示す。
/** 年齢が一致するデータを検索 */ private String searchByAge( SQLiteDatabase db, int age ){ // Cursorを確実にcloseするために、try{}〜finally{}にする Cursor cursor = null; try{ // name_book_tableからnameとageのセットを検索する // ageが指定の値であるものを検索 cursor = db.query( "name_book_table", new String[]{ "name", "age" }, "age = ?", new String[]{ "" + age }, null, null, null ); // 検索結果をcursorから読み込んで返す return readCursor( cursor ); } finally{ // Cursorを忘れずにcloseする if( cursor != null ){ cursor.close(); } } } /** 検索結果の読み込み */ private String readCursor( Cursor cursor ){ String result = ""; // まず、Cursorからnameカラムとageカラムを // 取り出すためのインデクス値を確認しておく int indexName = cursor.getColumnIndex( "name" ); int indexAge = cursor.getColumnIndex( "age" ); // ↓のようにすると、検索結果の件数分だけ繰り返される while( cursor.moveToNext() ){ // 検索結果をCursorから取り出す String name = cursor.getString( indexName ); int age = cursor.getInt ( indexAge ); result += name + " さん(" + age + " 歳)\n"; } return result; }
query()メソッドを使って検索する部分と、検索結果をCursorオブジェクトから取り出す部分に分けてみた。まず、query()メソッドで検索する部分(上記サンプルのsearchByAge()メソッド)について説明しよう。
query()メソッドにはたくさんの引数があるが、この例では必要最低限のものだけを指定している。第1引数には検索対象のテーブル名を指定する(省略不可)。第2引数には取得するカラム名を指定する。これはnullを与えて省略できる(その場合、テーブルの全カラムが取得されることになる)。
ややこしいのが第3、第4引数だ。第3引数には、検索条件を記述する。そして、第4引数で検索条件に埋め込むパラメータをString型の配列で指定する。第3引数の検索条件は、SQLのWhere句に当たり、この例では“age=?”としている。この“?”と書いている部分が、第4引数で指定した文字列に置き換わる。
検索条件には、複数の埋め込みパラメータを設定できる。例えば、名前と年齢の両方が一致するデータを検索したい場合は以下のようになる。
query()の残りの引数は、SQLのgroup by句、having句、order by句などに当たる。今回は取りあえずnullを指定しておく。
次に、Cursorオブジェクトから検索結果を取り出す処理(上記サンプルのreadCursor()メソッド)について説明する。
……とはいえ、なかなか言葉では説明しづらいので上記のサンプルを参照してほしい。
Cursorオブジェクトには、検索された件数分のデータが格納されており、moveToNext()メソッドで1件ずつデータを読み進めては、結果を取り出していく。そして、「これ以上格納されているデータがない」という状態まで読み込みを進めると、moveToNext()がfalseを返すため、ここで読み込み処理は終了となる。while()句の中で、いきなりmoveToNext()を実行しているので、最初の1件を読み飛ばしているように見えるが、実は検索直後は「0件目」を指した状態になっているので、上記の処理で問題ない。
次に、データの削除について説明する。削除処理の例は以下の通りだ。
/** 年齢を条件に削除 */ private void delByAge( SQLiteDatabase db, int age ){ db.delete( "name_book_table", "age = ?", new String[]{ "" + age } ); } /** 無条件で削除(全削除) */ private void delAllEntry( SQLiteDatabase db ){ db.delete( "name_book_table", null, null ); }
削除処理には、SQLiteDatabaseのdelete()メソッドを使用する。第1引数は削除対象のテーブル名、第2、第3引数は削除条件で、query()メソッドの検索条件と同じ形式で指定する。検索条件はnullで省略できる。その場合、テーブル上の全データが削除対象となる。delete()メソッドの結果は、実際に削除された件数がlong型で返される。
最後に、データの更新についてだ。実装例は以下のようになる。
/** 特定の年齢のデータを更新 */ private void updateEntry( SQLiteDatabase db, int targetAge, String newName, int newAge ){ // 更新内容はContentValuesに格納しておく ContentValues val = new ContentValues(); val.put( "name", newName ); val.put( "age" , newAge ); // 更新するデータの条件はquery()やdelete()と同じように記述する db.update( "name_book_table", val, "age = ?", new String[]{ "" + targetAge } ); }
データの更新は、SQLiteDatabaseのupdate()メソッドを使用する。第1引数はやはりテーブル名を指定する。第2引数はデータの更新内容で、insert()のときと同じようにContentValuesに格納した状態で受け渡す。第3、第4引数は「どのデータを更新する」という条件の指定で、query()やdelete()のときと同じように指定する。update()メソッドの結果は、実際に更新された件数がlong型で返される。
今回は、AndroidでSQLiteデータベースを使用する基本的な方法を紹介した。この内容でもデータベースを使用したアプリケーションを十分に作成できるが、実はAndroidでSQLiteを使うに当たっては、細かい注意点が幾つか存在する。それらの注意点については、次回のTipsであらためて紹介する。
≫連載「Androidアプリケーション開発者のためのTips集」の目次
Copyright © ITmedia, Inc. All Rights Reserved.