web-dev-qa-db-ja.com

Androidルームが重複するエンティティを挿入します

アプリケーションのデータベースとのやり取りにAndroidのRoomライブラリを使用していますが、データベースに重複したエントリが挿入されるのを防ぐ方法に困惑しています。

これは簡単なことのように思えるので、何かを見逃しているように感じます。私は、この主題に関連する単語のさまざまな組み合わせをGoogleで検索しましたが、役に立ちませんでした。

基本的に、サンプルの1つが挿入とクエリに使用することを使用しています。

エンティティ:

@Entity(tableName = "cameras")
public class CameraEntity {
    @PrimaryKey(autoGenerate = true)
    private int id;
    private Integer accountId;
    private Integer dvrId;
    private String vendorId;
    ...
}

DAO:

@Dao
public interface CameraDao {

    @Query("SELECT * FROM cameras")
    Flowable<List<CameraEntity>> getCameras();

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insertAll(List<CameraEntity> values);
}

ルームライブラリに関して、データを挿入するタイミングに関するルールを設定する方法はありますか?私が読んだある投稿では、自動インクリメントIDにより、各アイテムが主キーの点で一意になっていると述べました。それが本当なら、このライブラリを使用している他の人はそれをどのように説明していますか?

ありがとう!

8
andsec

自動生成された主キーは、主キーとして本当に必要な場合にのみ使用してください。データに自然な主キーがある場合は、それを使用して、REPLACEが何を行うかという点で一意性を決定します。

自動生成された主キーが必要で、他の列(または列の組み合わせ)も一意にしたい場合は、列に 一意のインデックス を追加します。これも影響しますREPLACE

14
CommonsWare

この状況は、ルームデータベースを使用した最初のアプリケーションで停止しました。その列データが存在する場合、何かが必要ですpdate他のデータが行にありますinsertテーブルに

私は1つの主キーと1つのuid(ここではaccountIdまたはdvrId)を持っていますが、これも主キーと同様です繰り返さないでください

これを行うには、indicesに対してEntityを作成し、置換したくないすべての列をこのように配置する必要があります

@Entity(tableName = "cameras", indices = [Index(value = ["accountId","dvrId"], unique = true)])
public class CameraEntity {
    @PrimaryKey(autoGenerate = true)
    private int id;
    private Integer accountId;
    private Integer dvrId;
    private String vendorId;
}

そして、交換戦略を選択することを忘れないでください

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertAll(List<CameraEntity> values);

any of idであり、accountIdとdvrIdが同じ列に存在する場合、データは更新されます。そうでない場合、データは新しい行に挿入されます

それが役に立てば幸い

4
Radesh