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の使い方の紹介でした。

