AndroidTips | SQLite3データベースとCursorについて

この記事は2014年2月10日に書かれたものです。内容が古い可能性がありますのでご注意ください。


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オブジェクト


  • onUpdate()
  • データベースが展開されたときに呼ばれる。

    @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に表示させてみます。
1

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



文字だけだとわかりにくいので図にしてみました。

  • 上から
  • 1

  • 横から
  • 2



この「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についてもう少し深く記述してみます。

  • このエントリーをはてなブックマークに追加

PAGE TOP