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()メソッドでカーソルの位置を次に移動させる。