読者です 読者をやめる 読者になる 読者になる

コンピュータクワガタ

かっぱのかっぱによるコンピュータ関連のサイトです

Androidアプリ入門 No.69 SQLiteの使用 SQLiteを使った簡単なアプリ

SQLiteの基本

SQLiteを使った簡単なアプリ

まず、SQLiteを使用した簡単なアプリを作り、どのような作りになるのか確認する。

項目 内容
Project name DbTest
Build Target Android 1.6
Application name DbTest
Package name sample.dt
Create Activity DbTest
Min SDK Version 4

まず、レイアウトのmain.xmlを以下のようにする。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<Button
    android:id="@+id/readButton"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="データ読み込み"
    />
<TextView
    android:id="@+id/resultTextView"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    />
</LinearLayout>

次に、データベースを操作するDatabaseHelper.javaを以下に示す。このクラスは、SQLiteOpenHelperクラスを継承して作成する。

package sample.dt;

import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "testdb";

    private static final String CREATE_TABLE = "CREATE TABLE emp ("
            + "key INTEGER PRIMARY KEY AUTOINCREMENT," + "name TEXT," + "age INTEGER" + ")";

    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, 1);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_TABLE);

        insert(db, "エクレア", 21);
        insert(db, "フローズンヨーグルト", 22);
        insert(db, "ハニカム", 30);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS emp");
        onCreate(db);
    }

    public void insert(SQLiteDatabase db, String name, int age) {
        ContentValues cv = new ContentValues();
        cv.put("name", name);
        cv.put("age", age);
        db.insert("emp", "", cv);
    }
}

最後に、DbTest.javaを以下に示す。ボタンを押すとデータベースの内容を読み込み表示する。

package sample.dt;

import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class DbTest extends Activity {
    private Button readButton;
    private TextView resultTextView;
    private DatabaseHelper databaseHelper;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // DB作成
        databaseHelper = new DatabaseHelper(getApplicationContext());

        readButton = (Button) findViewById(R.id.readButton);
        readButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                read();
            }
        });
        resultTextView = (TextView) findViewById(R.id.resultTextView);
    }

    private void read() {
        SQLiteDatabase db = databaseHelper.getReadableDatabase();
        Cursor cursor = db.query("emp", new String[] { "name", "age" }, null, null, null, null,
                null);
        cursor.moveToFirst();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < cursor.getCount(); i++) {
            sb.append(cursor.getString(0)).append(",");
            sb.append(cursor.getInt(1)).append("\n");
            cursor.moveToNext();
        }
        cursor.close();
        resultTextView.setText(sb.toString());
    }
}

実行結果は以下。

ここでデータベース操作の方法を解説する。まず、データベースを操作するためにSQLiteOpenHelperクラスを継承する。継承後にオーバーライドすべきメソッドはonCreateとonUpgradeとなる。まず、onCreateから確認する。onCreateの定義は以下となる。

public abstract void onCreate(SQLiteDatabase db)

引数の詳細は以下。

引数 説明
db データベースのオブジェクト。

onCreateはデータベースを作成する最初だけ呼び出される。通常、このメソッドでdbに対してDDLを発行しテーブルを作成したり、初期データを登録したりする。
次に、onUpgradeメソッドの定義は以下となる。

public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)

引数の詳細は以下。

引数 説明
db データベースのオブジェクト。
oldVersion 古いデータベースのバージョン。
newVersion 新しいデータベースのバージョン。

onUpgradeはデータベースがアップグレードする必要がある場合に呼ばれる。データベースのアップグレードはそれをDROPしたり、新しいテーブルを追加したりするために使用する。今回は、テーブルを再作成しているだけである。
次に、SQLiteDatabaseクラスについて確認する。まずは、execSQLメソッドについて確認する。execSQLメソッドの定義は以下となる。

public void execSQL(String sql)

引数の詳細は以下。

引数 説明
sql 実行するSQL

execSQLは1つのSQLを実行する。SQLは問い合わせ(SELECT文)ではないものが対象となる。今回は、CREATE TABLEとDROP TABLEを実行している。
もうひとつ今回のサンプルで使用しているのは、insertメソッドとなる。insertメソッドの定義は以下となる。

public long insert(String table, String nullColumnHack, ContentValues values)

引数の詳細は以下。

引数 説明
table insertするテーブル名。
nullColumnHack テーブルに値を挿入する際に、valuesが空の場合に使われる。nullColumnHackに指定された列には、明示的にNULLが割り当てられる。
values insertする値。ContentValuesクラスについては後述。

ここでinsertする際に使用したContentValuesについて解説する。ContentValuesは型が決まっているMapのような動きをする。ContentValues#putメソッドを用いてinsertで格納する値を設定する。具体的にputメソッドは以下のような定義になっている。

public void put(String key, 型 value)

引数の詳細は以下。汎用的に使えるが、ここではデータベース操作に使う前提で説明する。

引数 説明
key 列名。
value 列に格納する値。

第2引数の型には、Byte、Short、Integer、Long、Float、Double、Boolean、String、byte[]が入る。型が保証されているため非常に使いやすい。実際に発行されるINSERT文では、keyに指定された列名が自動的にマッピングされINSERT文が作成される。
最後にデータを取得する例を解説する。まず、データベースを操作するためにActivity側でSQLiteDatabaseオブジェクトを取得する。

SQLiteDatabase db = databaseHelper.getReadableDatabase();

その後、そのオブジェクトに対してSELECT文を発行する。今回の例では単純に発行するのではなく、queryメソッドで発行している。queryメソッドの定義は以下のようになる。

public Cursor query(String table, String[] columns, String selection,
String[] selectionArgs, String groupBy, String having, String orderBy)

引数の詳細は以下。

引数 説明
table テーブル名
columns SELECT文の結果取得する列名。
selection WHERE句をWHEREを除いて指定する。
selectionArgs WHERE句で指定された?を置き換える文字列。具体的な例は後述する。
groupBy GROUP BY句をGROUP BYを除いて指定する。
having HAVING句をHAVINGを除いて指定する。
orderBy ORDER BY句をORDER BYを除いて指定する。

queryを指定するとCursorオブジェクトが取得できる。そのCursorを使用してデータを取得する。先ほどの例で実際にCursorを使用している部分を見る。

Cursor cursor = db.query("emp", new String[] { "name", "age" }, null, null, null, null, null);
cursor.moveToFirst();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < cursor.getCount(); i++) {
    sb.append(cursor.getString(0)).append(",");
    sb.append(cursor.getInt(1)).append("\n");
    cursor.moveToNext();
}
cursor.close();

Cursorを取得した後、Cursor#moveToFirst()メソッドで取得した一覧の先頭に移動している。その後、Cursor#getCount()メソッドで取得した一覧の件数を取得している。
その一覧に対して、Cursor#getString(列番号)やCursor#getInt(列番号)メソッドを用いて現在の行の値を列番号で取得する。Cursorはその名前の通り特定の1行を指示しているため、次の行を確認するためにはCursor#moveToNext()メソッドでカーソルの位置を次に移動させる。

広告