モケラ

Tech Sheets

mokelab

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

一覧に戻る