[解決済み] Android Room Persistence Library。アップサート
2022-08-25 09:44:19
質問
Android の Room 永続化ライブラリには、オブジェクトまたはコレクションに対して機能する @Insert および @Update アノテーションが含まれています。しかし、私は、データがデータベースに存在するかどうかわからないため、UPSERT を必要とするユースケース (モデルを含むプッシュ通知) を持っています。
Sqliteはネイティブにupsertを持っておらず、回避策はこちらで説明されています。 SO質問 . そこにある解決策を考えると、Roomにどのように適用するのでしょうか?
より具体的には、どのようにしたら、外部キー制約を破らない Room の挿入または更新を実装できますか? onConflict=REPLACE で挿入を使用すると、その行への外部キーの onDelete が呼び出されます。私の場合、onDelete はカスケードを引き起こし、行を再挿入すると、その外部キーを持つ他のテーブルの行が削除されます。これは意図された動作ではありません。
どのように解決するのですか?
こんな感じでBaseDaoを作ればいいのかもしれません。
アップサートを@Transactionで保護する。 挿入に失敗したときだけ更新するようにする。
@Dao
public abstract class BaseDao<T> {
/**
* Insert an object in the database.
*
* @param obj the object to be inserted.
* @return The SQLite row id
*/
@Insert(onConflict = OnConflictStrategy.IGNORE)
public abstract long insert(T obj);
/**
* Insert an array of objects in the database.
*
* @param obj the objects to be inserted.
* @return The SQLite row ids
*/
@Insert(onConflict = OnConflictStrategy.IGNORE)
public abstract List<Long> insert(List<T> obj);
/**
* Update an object from the database.
*
* @param obj the object to be updated
*/
@Update
public abstract void update(T obj);
/**
* Update an array of objects from the database.
*
* @param obj the object to be updated
*/
@Update
public abstract void update(List<T> obj);
/**
* Delete an object from the database
*
* @param obj the object to be deleted
*/
@Delete
public abstract void delete(T obj);
@Transaction
public void upsert(T obj) {
long id = insert(obj);
if (id == -1) {
update(obj);
}
}
@Transaction
public void upsert(List<T> objList) {
List<Long> insertResult = insert(objList);
List<T> updateList = new ArrayList<>();
for (int i = 0; i < insertResult.size(); i++) {
if (insertResult.get(i) == -1) {
updateList.add(objList.get(i));
}
}
if (!updateList.isEmpty()) {
update(updateList);
}
}
}
関連
-
[解決済み] Androidのソフトキーボードをプログラムで閉じる/隠すにはどうすればよいですか?
-
[解決済み] Androidでアクティビティ起動時にEditTextにフォーカスが当たらないようにする方法
-
[解決済み] Androidの「コンテキスト」とは何ですか?
-
[解決済み] SQLite - UPSERT *not* INSERT or REPLACE
-
[解決済み】Android UserManager.isUserAGoat()の正しい使用例?)
-
[解決済み】Android Studioです。jarをライブラリとして追加しますか?
-
[解決済み】ルームパーシスタンスライブラリ。すべて削除
-
[解決済み] google-services.jsonって実際何してるの?
-
[解決済み] アンドロイドボタンセレクター
-
[解決済み] SQLite UPSERT / UPDATE OR INSERT
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] SQLite - UPSERT *not* INSERT or REPLACE
-
[解決済み] AndroidでラジオボタンにOnClickListenerを設定するには?
-
[解決済み] Androidのソースコードにある@hideの意味とは?
-
[解決済み] handler.postDelayed()を停止する。
-
[解決済み] onCreate(Bundle savedInstanceState)とは?
-
[解決済み] アンドロイドのクライアントでヒープアップデートを有効にする方法
-
[解決済み] フラグメント間の値の受け渡し方法
-
[解決済み] EditTextの右側のDrawableにonClickListenerを設定する [重複] [重複
-
[解決済み] アンドロイドのdatepickerダイアログで最大の日付を設定するには?
-
[解決済み] Androidの環境設定。ユーザーが環境設定画面を使用していない場合、デフォルト値を読み込むにはどうすればよいですか?