Android Room Persistence Library: Upsert Ask Question

Android Room Persistence Library: Upsert Ask Question

Android's Room persistence library graciously includes the @Insert and @Update annotations that work for objects or collections. I however have a use case (push notifications containing a model) that would require an UPSERT as the data may or may not exist in the database.

Sqlite doesn't have upsert natively, and workarounds are described in this SO question. Given the solutions there, how would one apply them to Room?

もっと具体的に言うと、Room で挿入または更新を実装して、外部キー制約を破らないようにするにはどうすればよいでしょうか。 onConflict=REPLACE を指定して挿入を使用すると、その行の外部キーの onDelete が呼び出されます。私の場合、onDelete によってカスケードが発生し、行を再挿入すると、外部キーを持つ他のテーブルの行が削除されます。これは意図された動作ではありません。

ベストアンサー1

編集:

@Tunji_D が述べたように、Room は@Upsertバージョン 2.5.0-alpha03 から正式にサポートされます。(リリースノート

彼を確認してください答え詳細については。

古い答え:

おそらく、BaseDao を次のように作成できるでしょう。

@Transaction を使用して upsert 操作を保護し、挿入が失敗した場合にのみ更新を試行します。

@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);
        }
    }
}

おすすめ記事