Android(sqlite3)のblobで保存、検索する方法

Androidではよく、画像とかをSDカードに保存とかやったりする場合があると思いますが、端末によってはSDカードがなかったりする場合もあると思います。
そういう場合には、blobで保存しておくと、結構便利だったりするのでその方法を書いてみたいと思います。


まずDBを定義します。
SQLiteOpenHelperを継承したクラスを作成します。

public class SampleDbOpenHelper extends SQLiteOpenHelper {
	private static final String DB = "sample.db";
	private static final int DB_VERSION = 1;
	
	public SampleDbOpenHelper(Context context) {
		super(context, DB, null, DB_VERSION);
	}
	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL(SampleDao.TABLE_SAMPLE);
	}
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
	}
}


テーブルを操作するクラスを作ります。

public class SampleDao {
	private static final String TABLE = "sample_table";
	
	private static final String COLUMN_ID = "id";
	private static final String COLUMN_BLOB = "object_blob";
	
	public static final String TABLE_SAMPLE =
		"create table " + TABLE + "(" +
		COLUMN_ID + " integer primary key," +
		COLUMN_BLOB + " blob);" ;
}

とりあえず、sample_tableというテーブルにid,object_blobという2つのカラムを持たせてます。


最初はinsertをおこなう方法です。
SampleDaoクラスに以下のメソッドを追加します。

	public static long insert(Context context, byte[] blob) { 
		SQLiteDatabase db = null;
		try {
			SampleDbOpenHelper helper = new SampleDbOpenHelper(context);
			db = helper.getWritableDatabase();
			ContentValues values = new ContentValues();
			values.put(COLUMN_BLOB, blob);

			return db.insert(TABLE, null, values);
		} finally {
			if (db != null) {
				db.close();
			}
		}		
	}

blobのデータはbyte配列として登録します。


次は取得方法です。
SampleDaoクラスに以下のメソッドを追加します。

	public static byte[] getBlob(Context context, String id) {
		SQLiteDatabase db = null;
		Cursor cursor = null;
		try {
			SampleDbOpenHelper helper = new SampleDbOpenHelper(context);
			db = helper.getReadableDatabase();
			String sql = String.format("select %s from %s where %s = ?", 
					COLUMN_BLOB, TABLE, COLUMN_ID);
			String[] args = {id};
			
			cursor = db.rawQuery(sql, args);
			
			if (cursor.moveToFirst()) {
				return cursor.getBlob(0);
			}
			return null;
		} finally {
			if (cursor != null) {
				cursor.close();
			}
			if (db != null) {
				db.close();
			}			
		}		
	}

上記のような感じでcursor.getBlobで取得できます。
例えば、このblobデータが画像データだったりすると以下のような感じでBitmapに変換できます。

BitmapFactory.decodeByteArray(blob, 0, blob.length); // blobはbyte[]です

結構簡単にblobが扱えるんですが、あまりでかいサイズを格納しようとすると、処理に時間がかかりエラーになったりするので、登録前にオブジェクトのサイズをみて、一定以下のサイズのみ登録って感じにしたほうがいいかもです。