JAVA:IT TRICK

SQLiteサンプル

AndroidでSQLiteを使った簡易メモアプリです。このサンプルを通してSQLiteでのデータ永久化について説明します。
  • このエントリーをはてなブックマークに追加
  • Clip to Evernote
  • IT TRICK RSS

AndroidでSQLiteを使った簡易メモアプリです。このアプリの概要としては、テキストを入力し、追加ボタンをクリックすることで、入力したテキストをDBに追加します。また、DBにある最新の全データを画面下部に表示するという非常にシンプルなアプリです。

今回のメモアプリで使用するDBを「memodb」とし、メモを記憶するためのテーブルを「memo」とします。また、メモテーブルの主キーは自動的に数字が振られるように「integer primary key autoincrement」として定義しています。

memodb.sql
create table memodb (
        rowid integer primary key autoincrement,
        data text not null
)

まず、最初にDBから取得した一行のデータを保持するためのEntityクラス「MyDBEntity.java」を作成します。

MyDBEntity.java
package android.test;

public class MyDBEntity {

    private int rowId;

    private String value;

    public void setRowId(int rowId) {
            this.rowId = rowId;
    }

    public int getRowId() {
            return rowId;
    }

    public void setValue(String value) {
            this.value = value;
    }

    public String getValue() {
            return value;
    }

}

DBのHelperクラス「MyDBHelper.java」を作成します。DBのHelperクラスの詳細については「SQLiteOpenHelperクラス」を参照してください。

MyDBHelper.java
package android.test;

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

public class MyDBHelper extends SQLiteOpenHelper {

	private static final String DB_NAME = "memodb";

    /** 「dbtest」テーブルの作成用SQL */
    private static final String CREATE_TABLE_SQL = "" +
                    "create table memo (" +
                            "rowid integer primary key autoincrement, " +
                            "data text not null " +
                    ")";

    /** 「dbtest」テーブルの削除用SQL */
    private static final String DROP_TABLE_SQL = "drop table if exists memo";

    /**
     * コンストラクタ(必須)
     * @param context
     * @param name
     * @param factory
     * @param version
     */
    public MyDBHelper(
                    Context context,
                    CursorFactory factory,
                    int version) {

            super(context, DB_NAME, factory, version);
    }

    /**
     * テーブルの生成(必須)
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
            db.execSQL(CREATE_TABLE_SQL);
    }

    /**
     * テーブルの再作成(必須)
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL(DROP_TABLE_SQL);
            db.execSQL(CREATE_TABLE_SQL);
    }

}

メモテーブルのDaoクラス「MemoDao.java」を作成します。Daoクラスの詳細については「DAOデザインパターン」を参照してください。

MemoDao.java

package android.test;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class MemoDao {

	// テーブルの定数
    private static final String TABLE_NAME = "memo";
    private static final String COLUMN_ID = "rowid";
    private static final String COLUMN_DATA = "data";
    private static final String[] COLUMNS = {COLUMN_ID, COLUMN_DATA};

    // SQLiteDatabase
    private SQLiteDatabase db;

    /**
     * コンストラクタ
     * @param db
     */
    public MemoDao(SQLiteDatabase db) {
            this.db = db;
    }

    /**
     * 全データの取得   ----------------①
     * @return
     */
    public List<MyDBEntity> findAll() {
            List<MyDBEntity> entityList = new  ArrayList<MyDBEntity>();
            Cursor cursor = db.query(
                            TABLE_NAME,
                            COLUMNS,
                            null,
                            null,
                            null,
                            null,
                            COLUMN_ID);

            while(cursor.moveToNext()) {
            	MyDBEntity entity = new MyDBEntity();
                    entity.setRowId(cursor.getInt(0));
                    entity.setValue(cursor.getString(1));
                    entityList.add(entity);
            }

            return entityList;
    }

    /**
     * 特定IDのデータを取得   ----------------②
     * @param rowId
     * @return
     */
    public MyDBEntity findById(int rowId) {
            String selection = COLUMN_ID + "=" + rowId;
            Cursor cursor = db.query(
                            TABLE_NAME,
                            COLUMNS,
                            selection,
                            null,
                            null,
                            null,
                            null);

            cursor.moveToNext();
            MyDBEntity entity = new MyDBEntity();
            entity.setRowId(cursor.getInt(0));
            entity.setValue(cursor.getString(1));

            return entity;
    }

    /**
     * データの登録   ----------------③
     * @param data
     * @return
     */
    public long insert(String value) {
            ContentValues values = new ContentValues();
            values.put(COLUMN_DATA, value);
            return db.insert(TABLE_NAME, null, values);
    }

    /**
     * データの更新   ----------------④
     * @param rowid
     * @param date
     * @return
     */
    public int update(MyDBEntity entity) {
            ContentValues values = new ContentValues();
            values.put(COLUMN_DATA, entity.getValue());
            String whereClause = COLUMN_ID + "=" + entity.getRowId();
            return db.update(TABLE_NAME, values, whereClause, null);
    }

    /**
     * データの削除   ----------------⑤
     * @param rowId
     * @return
     */
    public int delete(int rowId) {
            String whereClause = COLUMN_ID + "=" + rowId;
            return db.delete(TABLE_NAME, whereClause, null);
    }

}

データ永久化のための準備は以上になります。次はいよいよ画面です。まずmain.xmlは以下のように定義します。実際、このmain.xml内のID「showData」になっているLinearLayout内にDBのデータが出力されます。

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="#ffffff">

    <LinearLayout
    	android:layout_width="fill_parent"
    	android:layout_height="wrap_content"
    	android:orientation="horizontal"
    	android:padding="0px">

        <EditText
        	android:id="@+id/dataEdit"
        	android:layout_width="wrap_content"
        	android:layout_height="wrap_content"
        	android:layout_weight="1"
        	android:layout_margin="0px"/>
    	<Button
        	android:id="@+id/addButton"
        	android:text="追加"
        	android:layout_width="wrap_content"
        	android:layout_height="wrap_content"
        	android:layout_margin="0px"
        	android:onClick="addData"/>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/showData"
    	android:layout_width="fill_parent"
    	android:layout_height="wrap_content"
    	android:orientation="vertical"
    	android:padding="0px"
    	android:layout_marginTop="30px">
    </LinearLayout>

</LinearLayout>

最後にActivityを以下のように作成します。ここでのポイントはonCreate()メソッド、addData()メソッドとchangeData()メソッドです。

SQLiteTestActivity.java
package android.test;

import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

public class SQLiteTestActivity extends Activity {

	private MemoDao dao;
	private LinearLayout showData;
	private EditText dataEdit;

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

		// SQLiteの準備
		MyDBHelper helper = new MyDBHelper(this, null, 1);
		SQLiteDatabase db = helper.getReadableDatabase();
		dao = new MemoDao(db);

		// データ入力欄の初期設定
		dataEdit = (EditText)findViewById(R.id.dataEdit);
		dataEdit.setOnKeyListener(new AddressBarOnKeyListener());

		// データ出力Viewグループの取得
		showData = (LinearLayout)findViewById(R.id.showData);

		// 表示データの更新
		changeData();
	}


	/**
	 * 追加ボタンのクリックイベント
	 * @param view
	 */
	public void addData(View view) {

		// データの追加
		dao.insert(dataEdit.getText().toString());

		// 入力欄のクリア
		dataEdit.setText(null);

		// 表示データの更新
		changeData();
	}


	/**
	 * 表示データの更新
	 */
	private void changeData() {

		// 表示中のデータを一旦すべてクリアする。
		showData.removeAllViews();

		// DBからすべてのデータを取得する。
		List<MyDBEntity> entityList = dao.findAll();

		// データを表示領域に追加する
		for(MyDBEntity entity: entityList) {
			TextView textView = new TextView(this);
			textView.setText(entity.getRowId() + ": " + entity.getValue());
			showData.addView(textView);
		}
	}


	// ソフトキーボードの「確定」が押された時にソフトキーボードを消す
	private class AddressBarOnKeyListener implements OnKeyListener {

		public boolean onKey(View view, int keyCode, KeyEvent event) {

			//EnterKeyが押されたかを判定
			if (event.getAction() == KeyEvent.ACTION_DOWN
					&& keyCode == KeyEvent.KEYCODE_ENTER) {

			//ソフトキーボードを閉じる
			InputMethodManager inputMethodManager =
				(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
			inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);

			return true;
			}

			return false;
		}
	}
}

■onCreate()メソッド内でまずMyDBHelperクラスのインスタンスを生成します。getReadableDatabase()メソッドを利用して、生成したインスタンスからSQLiteDatabaseオブジェクトを取得します。この時、DB「memodb」がまだ作成されていなければ、自動的に作成されます。次にSQLiteDatabaseオブジェクトを引数にMemoDaoクラスのインスタンスを生成します。これでDBの準備が完了です。今後DBに対しての操作はすべてMemoDaoクラスを通して行うことになります。最後に画面に登録データを表示するためにchangeDataメソッドを呼び出しています。

■addData()メソッドは「追加」ボタンのキーイベントメソッドです。「追加」ボタンが押下された場合、入力したテキストを取得し、MemoDaoのinsert()メソッドを使ってDBに登録を行います。その後、画面の表示を更新するためにchangeData()メソッドを呼び出しています。

■changeData()メソッドでは、まず画面の「showData」内の子ビューをすべて一旦削除します。次にMemoDaoクラスのfindAll()メソッドを使ってDB内の全データを取得し、取得したデータを順番にTextViewに入れて「showData」内に追加しています。