【AndroidでSQLiteを制する】SQLiteDatabase#updateを使用してデータをアップデートする

このエントリーを Google ブックマーク に追加
Pocket
[`yahoo` not found]

SQLデータベース内のテーブルのデータを更新します。
今回はSQLiteDatabaseに定義されているアップデートを行うコンビニエンスメソッドを使用します。

SQLiteDatabase#updateを使用する

SQLiteDatabase#updateはテーブルのデータを更新するコンビニエンスメソッドです。
SQLiteDatabase#updateには4つの引数があります。
String table データベース内のテーブル名を指定します。
ContentValues values ContentValues を使用してアップデートするデータを設定して渡します。
ContentValues#putの第1引数にテーブルのカラム名を、第2引数にはデータを設定します。
String whereClause WHERE句を指定します。
「[カラム名] = ? AND [カラム名] = ? 」のようにクエリに条件を設定します。
?はwhereArgsで指定します。
WHERE句が不要な場合はnullを指定してください。
String[] whereArgs String whereClauseで指定した「?」を埋めるための文字列を配列で指定できます。
「?」の数よりも配列の要素数が多い場合は例外が発生します。
WHERE句に「?」が存在しない場合はnullを指定してください。
このメソッドを使用してBookDAOにupdateメソッドを実装します。
今回は指定したidのデータをBookDTOの内容を使用して更新します。
BookDAO
  public static long update(Context context , BookDTO bookDTO , String id){
      SQLiteDatabase sqLiteDatabase = getSqLiteDatabase(context,true);
      long rowId = sqLiteDatabase.update(
              LoadToSQLiteMasterContract.Book.TABLE_NAME,
              convertContentValues(bookDTO),
              LoadToSQLiteMasterContract.Book._ID + " = ? ",
              new String[]{id}
      );
      return rowId;
  }
SQLiteActivityにBookDAO#updateメソッドを使用し、SQLiteActivity#updateBookを実装します。
  private void updateBook(BookDTO book) {
      long rowId = BookDAO.update(getApplicationContext() , book , "1");
      Toast.makeText(this, "rowId:" + rowId , Toast.LENGTH_SHORT).show();
  }

SQLiteDatabase#updateWithOnConflictを実際に使用する

SQLiteDatabase#updateWithOnConflictはテーブルのデータを更新するコンビニエンスメソッドです。
SQLiteDatabase#updateとの違いは5つ目の引数に競合解消アルゴリズムを指定できることです。
SQLiteDatabase#updateWithOnConflictには5つの引数があります。
String table データベース内のテーブル名を指定します。
ContentValues values ContentValues を使用してアップデートするデータを設定して渡します。
ContentValues#putの第1引数にテーブルのカラム名を、第2引数にはデータを設定します。
String whereClause WHERE句を指定します。
「[カラム名] = ? AND [カラム名] = ? 」のようにクエリに条件を設定します。
?はwhereArgsで指定します。
WHERE句が不要な場合はnullを指定してください。
String[] whereArgs String whereClauseで指定した「?」を埋めるための文字列を配列で指定できます。
「?」の数よりも配列の要素数が多い場合は例外が発生します。
WHERE句に「?」が存在しない場合はnullを指定してください。
int conflictAlgorithm SQLiteには制約違反が発生した場合の解消アルゴリズムが複数実装されています。 この引数にはSQLiteDatabaseに定義されています。
CONFLICT_ABORT ON CONFLICT ABORTを表す定数です。 制約違反が発生した時にロールバックが発生しません。 そのため、同じトランザクション内の以前に実行されたSQLによる変更は保持されます。 この設定がデフォルトになっています。
CONFLICT_FAIL ON CONFLICT FAILを表す定数です。 制約違反が発生した時に、コマンドの戻り値としてコード[SQLITE_CONSTRAINT]を返却して打ち切られます。 しかし、制約違反が発生する前に実行されたSQLによる変更は保持され取り消されません。
CONFLICT_IGNORE ON CONFLICT IGNOREを表す定数です。 制約違反が発生した時に、制約違反を含む挿入や変更のコマンドは無視され、後続の処理は継続されます。 この時、エラーは返されません。
CONFLICT_NONE 制約違反時のアクションを指定しない場合に使用します。
CONFLICT_REPLACE ON CONFLICT REPLACEを表す定数です。 ユニーク制約違反が発生した場合は既存の行を削除した後に、挿入または更新が必ず行われます。 NOT NULL制約違反が発生した場合は該当の列にはデフォルト値で更新されます。しかし、列にデフォルト値が設定されていない場合はABORTアルゴリズムが使用されます。 CHECK制約違反が発生した場合はIGNOREアルゴリズムが使用されます。 この競合解消方法は制約を満たすために行を削除するときに行の削除トリガーを起動しません。 この動作は将来のリリースで変更される可能性があります。
CONFLICT_ROLLBACK ON CONFLICT ROLLBACKを表す定数です。 制約違反が発生するとすぐにROLLBACKが発生し現在のトランザクションが終了します。 この時、SQLITE_CONSTRAINTの戻りコードでSQLが異常終了します。 トランザクションが有効でない場合に制約違反が発生するとABORTと同じように動作します。
このメソッドを使用してBookDAOにupdateWithOnConflictメソッドを実装します。
今回は競合解消アルゴリズムにCONFLICT_REPLACEを設定することで競合が発生した場合は既存のデータを削除します。
BookDAO
  public static long updateWithOnConflict(Context context , BookDTO bookDTO){
      SQLiteDatabase sqLiteDatabase = getSqLiteDatabase(context,true);
      long rowId = sqLiteDatabase.updateWithOnConflict(
              LoadToSQLiteMasterContract.Book.TABLE_NAME,
              convertContentValues(bookDTO),
              "",
              null,
              SQLiteDatabase.CONFLICT_REPLACE
      );
      return rowId;
  }
SQLiteActivityにBookDAO#updateWithOnConflictメソッドを使用し、SQLiteActivity#updateWithOnConflictBookを実装します。
  private void updateWithOnConflictBook(BookDTO book) {
      long rowId = BookDAO.updateWithOnConflict(getApplicationContext() , book);
      Toast.makeText(this, "rowId:" + rowId , Toast.LENGTH_SHORT).show();
  }