AndroidTips | SQLite3データベースとCursorについて
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についてもう少し深く記述してみます。