Data Access Objectを作る
最終更新日:2015-07-07
作成したSQLiteOpenHelperにテーブル操作(作成除く)を記述すると、SQLiteOpenHelperの役割が増えてしまうので、DAO(Data Access Object)を別途作成しましょう。
ここまでの実装はここにあります。
まずは列の定義を表すinterfaceから。
public interface TodoColumns extends BaseColumns {
String USER_ID = "user_id";
String TODO = "todo";
String MODIFIED_TIME = "modified_time";
String SERVER_ID = "server_id";
String SERVER_TIME = "server_time";
}
次に、DAO側。
class TodoDAO {
private static final String TABLE_NAME = "todo";
private static final String SQL_CREATE = "create table " + TABLE_NAME + "(" +
TodoColumns._ID + " integer primary key autoincrement," +
TodoColumns.USER_ID + " text," +
TodoColumns.TODO + " text," +
TodoColumns.MODIFIED_TIME + " integer," +
TodoColumns.SERVER_ID + " text," +
TodoColumns.SERVER_TIME + " integer)";
private SQLiteDatabase mDB;
TodoDAO(SQLiteOpenHelper helper) {
mDB = helper.getWritableDatabase();
}
static void createTable(SQLiteDatabase db) {
db.execSQL(SQL_CREATE);
}
Cursor query(String userId, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
String[] args;
// add user_id=? to selection
if (TextUtils.isEmpty(selection)) {
selection = TodoColumns.USER_ID + "=?";
args = new String[] { userId };
} else {
selection += " AND " + TodoColumns.USER_ID + "=?";
args = new String[selectionArgs.length + 1];
System.arraycopy(selectionArgs, 0, args, 0, selectionArgs.length);
args[args.length - 1] = userId;
}
return mDB.query(TABLE_NAME, projection, selection, args, null, null, sortOrder);
}
long insert(String userId, String serverId, long modifiedTime, long serverTime, String todo) {
ContentValues values = new ContentValues();
values.put(TodoColumns.USER_ID, userId);
values.put(TodoColumns.SERVER_ID, serverId);
values.put(TodoColumns.MODIFIED_TIME, modifiedTime);
values.put(TodoColumns.SERVER_TIME, serverTime);
values.put(TodoColumns.TODO, todo);
// SQLiteDatabase#insert() returns _id
return mDB.insert(TABLE_NAME, null, values);
}
}
テーブルの定義は次のようにしました。あとでサーバーとの同期を想定し、サーバーでのIDと更新時刻も保存するようにしています。
列名 | 型 | 説明 |
---|---|---|
_id | integer | 行ID。_idでintegerなのはお約束 |
user_id | text | ユーザーID |
todo | text | ユーザーが入力したToDo |
modified_time | integer | ローカルでの更新時刻。同期のときに使う |
server_id | text | このレコードのサーバー上でのID |
server_time | integer | このレコードのサーバー上での更新時刻。同期のときに使う |
insertとqueryでは、かならずユーザーIDを引数にとるようにしています。queryはそれっぽく条件をつけているものの、selectionにuser_idを含む指定があるとまずいかも。。。
余裕があれば自動テストも書いておくとよいでしょう。ここもContentProviderというよりは単なるSQLiteDatabaseの使い方の紹介でした。