SQLite3データベースとCursorについて
みなさん、こんにちは。
今回も当校の授業の中で生徒さんが混乱しがちな点を解説します。
Androidはライブラリ型のリレーショナルデータベースであるSQLite3を搭載しています。
今さらではありますが、このSQLite3とCursorについて説明します。
※データベースがなんたるかについては記述しません。
SQLiteOpenHelperクラスを継承
データベースの作成や初期設定、アップデートを実施する場合には、SQLiteOpenHelperクラスを使用します。
使い方はとても簡単で、新規クラスを作成しSQLiteOpenHelperクラスを継承させます。
そして以下のコンストラクタを呼び出します。
public MyOpenHelper(Context context) {
super(context, "DB", null, DB_VERSION);
}
| 引数名 | 用途 |
|---|---|
| context | 自オブジェクト |
| name | データベースの名前 |
| factory | クエリが呼ばれたときに返すサブクラス |
| version | 作成するデータベースのバージョン |
また、以下の2つの抽象メソッドを定義します。
- onCreate()
データベースを初めて作成するときのみ呼ばれる。
@Override
public void onCreate(SQLiteDatabase db) {}
| 引数 | 用途 |
|---|---|
| db | SQLiteDatabaseオブジェクト |
データベースが展開されたときに呼ばれる。
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
| 引数 | 用途 |
|---|---|
| db | SQLiteDatabaseオブジェクト |
| oldVersion | データベースの旧バージョン番号 |
| newVersion | データベースの新バージョン番号 |
それでは具体例を挙げてみます。
以下では下表のようにデータベースとテーブルを作成しています。
ここでは「DB」という名前のデータベースを作成し、「person」という名前のテーブルを作成しています。
personテーブルには初期値として「24歳の佐藤一郎さん」と「18歳の鈴木二郎さん」を登録しています。
package com.example.sqlitesample;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class Helper extends SQLiteOpenHelper {
final static private int DB_VERSION = 1;
public Helper(Context context) {
super(context, "DB", null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// SQL文の実行
// データベース作成
db.execSQL("create table person(" + "id INTEGER PRIMARY KEY," + " name text not null," + " age text" + ");");
// データベースに追加
db.execSQL("INSERT INTO person(name,age) VALUES ('佐藤 一郎', 24);");
db.execSQL("INSERT INTO person(name,age) VALUES (?, ?);", new Object[] { "鈴木 二郎", 18 });
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
データベースの参照
先ほど作成したデータベースの中身を、以下のようにListViewに表示させてみます。

Cursor(カーソル)は、データベースから取得したデータを表示する際に
package com.example.sqliteexample;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
public class MainActivity extends Activity implements OnItemClickListener {
private SQLiteDatabase db;
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// SQLiteOpenHelperクラス(もしくはそれを継承したサブクラス:ここではHelperクラス)をインスタンス化
Helper myHelper = new Helper(this);
// このActivity内では、データベースの読み込みのみを行うので、
// SQLiteOpenHelperクラスのgetReadableDatabase()を用いて、
// SQLiteDatabaseオブジェクトを取得
db = myHelper.getReadableDatabase();
// SQLiteDatabaseクラスのrawQueryメソッドを用いてCursorオブジェクトを取得
Cursor c = db.rawQuery("select rowid as _id," + Colum.NameColum + ","
+ Colum.AgeColum + " from " + Colum.TableName, null);
// 先頭行に移動
c.moveToFirst();
// アダプターを作成
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_2,
c,
new String[] {Colum.NameColum, Colum.AgeColum },
new int[] {android.R.id.text1, android.R.id.text2 }
);
listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// Cursor内での場所を特定することにより、選択した項目の場所を取得
Cursor cur = (Cursor) listView.getItemAtPosition(position);
// cur.getColumnIndex():カラムインデックスを取得
// cur.getString():リクエストしたカラムの値をString型で返す。
String str = cur.getString(cur.getColumnIndex(Colum.NameColum));
Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
}
}
細かい説明はプログラム内にコメントとして入れておきました。
さて引数の多いSimpleCursorAdapterの引数は以下の通りです。
| 引数名 | 用途 | |
|---|---|---|
| 第1引数 | context | 自オブジェクト |
| 第2引数 | layout | レイアウト設定 |
| 第3引数 | c | カーソルオブジェクト |
| 第4引数 | from | UIにバインドするデータを表す列名のリスト |
| 第5引数 | to | fromをセットするリソースID |
文字だけだとわかりにくいので図にしてみました。
この「android.R.layout.simple_list_item_2」というレイアウトで、「android.R.id.text1」と「android.R.id.text2」を設置しています。
そして「android.R.id.text1」に「Colum.NameColum」から取得した値を、「android.R.id.text2」に「Colum.AgeColum」から取得した値を設置しているイメージです。それがカラム内のデータ分だけ存在するイメージですね。
ちなみに「android.R.id.text1」も「android.R.id.text2」も、どちらもTextViewが1つだけ遅疑されているレイアウトファイルです。
次回はCusorについてもう少し深く記述してみます。

