Androidのデータベース「SQLite」の使い方は?
今回は、以下の記事の続編になります。
Androidアプリのデータ保存方法の一つ「SQLite」の使い方 SQLiteOpenHelper編
Androidアプリのデータ保存方法の一つ「SQLite」の使い方 行の追加・更新・削除編
これまで、データベースのオープンと、レコードの追加・更新・削除についての説明をしました。
今回は、SQLでいうselect文、レコードの検索について説明していきます。
一概にはいえませんが、データベースを取り扱う上で、コード的には最も実装する場面が多いのが、このselectじゃないかなと思います。
これから示すサンプルコードでは、「Androidアプリのデータ保存方法の一つ「SQLite」の使い方 SQLiteOpenHelper編で掲載しているサンプルコードにて、既にSQLiteDatabase型インスタンスを生成しているものとします。
変数名は、sdbとします。
なお、テーブル定義は、テーブル名は「bookmarklist」で、_id列とbookmark列の2列が存在する事とします。
※_id列については、別記事「Androidアプリで使用するSQLiteのテーブル作成時の注意点」を参照してください。
レコードの検索を行った後、検索結果は、Cursorというインスタンスとして返されてきます。
このCursorインスタンスの取得方法は、大きく2通りありますので、まずはその方法を紹介します。
SQLiteDatabase.query()の使い方
まずは一つ目の、SQLiteDatabase.query()メソッドの使い方を説明します。
final String[] columns = new String[]{“_id”,”bookmark”};
String where = “bookmark like ?”;
String param = “%android%”;
Cursor c =
sdb.query(“bookmarklist”,columns,where,new String[]{param},
null,null,”_id desc”,”10″);
SQLiteDatabase.query()メソッドの第一引数はテーブル名です。
第二引数は、取得する列名(カラム名、フィールド名)の配列を指定します。
第三引数、第四引数は取得するレコードの条件を指定します。
今回は、bookmark列の文字列に、「android」という文言が含まれる文字列、という条件にしています。
第五引数は、group by句を指定します。
第六引数は、Having句を指定します。
第七引数は、order by句を指定します。
第八引数は、limit句(取得するレコードの上限数)を指定します。
使わない場合は、nullを指定します。
今回の処理をSQL文で表現すると、以下のようになります。
select _id,bookmark
from bookmarklist
where bookmark like ‘%android%’
order by _id desc
limit 10
Cursorオブジェクトの操作方法は後述します。
SQLiteDatabase.rawQuery()の使い方
それでは次は、rawQuery()メソッドの使い方を説明します。
rawQuery()メソッドは、文字通り、生のクエリを使用します。
String sqlstr = “select _id,bookmark ” +
”from bookmarklist ” +
”where bookmark like ‘%android%’ ” +
”order by _id desc ” +
”limit 10″;
Cursor c = sdb.rawQuery(sqlstr);
SQLiteDatabase.rawQuery()メソッドの引数は、SQL文です。
個人的には、先ほどのquery()メソッドより使いやすいと思うんですが、どうでしょうか。
query()メソッドは、どの引数に何のパラメータを与えればよかったんだっけ?といちいち調べないといけなさそうなのですが、rawQuery()メソッドは明確です。
それに、inner joinやleft outer join等を使って、複数テーブルを結合させるようなSQLだったら、このrawQuery()の方がいいでしょう。
好き好きかもしれませんが、Androidアプリで使われる程度のSQLは難しいとは思えませんので、生のSQLを実行できるrawQuery()の方が、可読性もいいのではないかと思います。
あくまで個人的にはですけど。
ちなみに、rawQuery()はselect文専用です。
insert、update、delete等は、execSQL()メソッドを使います。
詳しくは下記をご覧下さい。
Androidアプリのデータ保存方法の一つ「SQLite」の使い方 行の追加・更新・削除編
スポンサーリンク
それでは、次はCursorインスタンスの基本的な使い方を見ていきましょう。
Cursorインスタンスの使い方
基本的には、取得したレコードを最初から最後までループで回して何かをする、という用法になると思います。
例えば以下のようなサンプルコードを見てください。
//query()またはrawQuery()の実行
Cursor c = -省略-;
if(c.moveToFirst()){
do{
long id = c.getLong(c.getColumnIndex(“_id”));
String bookmark = c.getString(c.getColumnIndex(“bookmark”));
System.out.println(id + “:” + bookmark);
}while(c.moveToNext());
}
単純に取得した全レコードを標準出力で出力させているだけですが、上からみてみましょう。
まず、最初のif文ではCursor.moveToFirst()を実行していますね。
これは、取得した結果に対するカーソルを先頭に移動させる、という意味です。
成功したらtrueが返却されます。
その後の処理は、このmoveToFirst()が成功したら実行する、という事です。
ちなみに、取得したレコード件数が0件であった場合は、moveToFirst()の戻り値はfalseになります。
次は、後判定のループ処理となってますね。
Cursor.moveToNext()は、カーソルを次のレコードへ移動させる、という意味合いです。
このmoveToNext()の戻り値は、次のレコードがあればカーソルを移動させてtrueを戻します。
次のレコードが無ければfalseを返します。
ちなみに、後判定としているのは、一番最初のレコードの処理を行う為です。
レコードの内容を取り出す処理は、それぞれの列の型に合わせて、getLong()、getString()、getInt()等を使います。
引数は、カラムのインデックスで、要は何列目にあるのか?の数値です。
これは、列名を引数にして、getColumnIndex()で取得できます。
なんとも回りくどい仕様です・・・。
なぜ、引数に列名を指定しても取れるようにオーバーロードしてくれなかったの?と言いたいトコロです。
もちろん、インデックスがわかっていれば、メソッドを使わずにベタ書きでもいいですが、途中でテーブル定義を変えちゃっても正しく動作するように、今回のように実装しておいた方がいいのではないかなと思います。
JSPやサーブレットなどで、DBを使ったシステムの経験があれば難なく理解できるかと思います。
しかし、携帯組込みでは、データベースを取り扱うなんて今までは無かったかと思いますが、大体理解できましたでしょうか。