Tips

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

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

みなさん、こんにちは。
今回も当校の授業の中で生徒さんが混乱しがちな点を解説します。

Androidはライブラリ型のリレーショナルデータベースであるSQLite3を搭載しています。
今さらではありますが、このSQLite3とCursorについて説明します。
※データベースがなんたるかについては記述しません。

SQLiteOpenHelperクラスを継承

データベースの作成や初期設定、アップデートを実施する場合には、SQLiteOpenHelperクラスを使用します。
使い方はとても簡単で、新規クラスを作成しSQLiteOpenHelperクラスを継承させます。
そして以下のコンストラクタを呼び出します。

1
2
3
public MyOpenHelper(Context context) {
  super(context, "DB", null, DB_VERSION);
}
引数名 用途
context 自オブジェクト
name データベースの名前
factory クエリが呼ばれたときに返すサブクラス
version 作成するデータベースのバージョン



また、以下の2つの抽象メソッドを定義します。

  • onCreate()
  • データベースを初めて作成するときのみ呼ばれる。

    1
    2
    @Override
    public void onCreate(SQLiteDatabase db) {}
    引数 用途
    db SQLiteDatabaseオブジェクト


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

    1
    2
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
    引数 用途
    db SQLiteDatabaseオブジェクト
    oldVersion データベースの旧バージョン番号
    newVersion データベースの新バージョン番号



それでは具体例を挙げてみます。
以下では下表のようにデータベースとテーブルを作成しています。
ここでは「DB」という名前のデータベースを作成し、「person」という名前のテーブルを作成しています。
personテーブルには初期値として「24歳の佐藤一郎さん」と「18歳の鈴木二郎さん」を登録しています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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(カーソル)は、データベースから取得したデータを表示する際に

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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についてもう少し深く記述してみます。

Androidアプリ開発の必須知識!JAVAプログラミングを学べる連載リンク

はじめてのJAVA 連載

Recent News

Recent Tips

Tag Search