Android Room вставляет повторяющиеся объекты

Я использую библиотеку Android Room для взаимодействия с базой данных в приложении, и я в некотором роде озадачен тем, как предотвратить вставку повторяющихся записей в базу данных.

Я чувствую, что мне что-то не хватает, потому что это должно быть просто сделать. Я искал в Google различные комбинации слов, относящихся к теме, но безрезультатно.

По сути, я использую то, что делает один из примеров, для вставки и запросов.

Лицо:

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

Что касается библиотеки Room, есть ли способ установить некоторые правила, когда следует вставлять данные? В одном сообщении, которое я прочитал, упоминалось, что идентификатор автоматического увеличения делает каждый элемент уникальным с точки зрения первичного ключа. Если это правда, то как другие используют эту библиотеку с учетом этого?

Спасибо!


person andsec    schedule 24.10.2017    source источник
comment
идентификатор автоматического увеличения делает каждый элемент уникальным с точки зрения первичного ключа - правильным. как предотвратить добавление повторяющихся записей в базу данных - как вы определяете повторяющиеся записи? У нас нет возможности узнать, отчасти потому, что ваша CameraEntity запись отредактирована.   -  person CommonsWare    schedule 24.10.2017
comment
Хорошая точка зрения. Я добавил еще несколько полей для обсуждения. Я бы определил повторяющиеся записи как что-либо с совпадающим vendorId (в данном случае String).   -  person andsec    schedule 24.10.2017
comment
Затем сделайте это первичным ключом. Или добавьте уникальный индекс.   -  person CommonsWare    schedule 24.10.2017
comment
@CommonsWare Замечательно, уникальный индекс, кажется, помогает! Спасибо! Я подумал, что это будет что-то простое, что я пропустил.   -  person andsec    schedule 24.10.2017


Ответы (2)


Используйте автоматически сгенерированный первичный ключ, только если это действительно то, что вам нужно в качестве первичного ключа. Если ваши данные имеют естественный первичный ключ, используйте его, и он определяет уникальность с точки зрения того, что будет делать REPLACE.

Если вам нужен автоматически сгенерированный первичный ключ, но вы также хотите, чтобы какой-то другой столбец (или комбинация столбцов) был уникальным, добавьте уникальный индекс столбца (столбцов), и это также повлияет на REPLACE.

person CommonsWare    schedule 24.10.2017
comment
OnUpdate = CASCADE заменит повторяющиеся записи, и эта ссылка объясняет, как мы можем применить уникальность к нескольким столбцам developer.android.com/training/data-storage/room/ - person xrnd; 23.01.2018
comment
@CommonsWare, как я могу разрешить повторяющиеся записи, мой room-database - это auto-replacing любые дубликаты ... см. [Это]: stackoverflow.com/questions/49728357/ - person Santanu Sur; 09.04.2018

Я застрял в этой ситуации в первом приложении с базой данных комнат. Мне нужно что-то, если данные этого столбца существуют, обновить другие данные в строке еще вставить в таблицу

У меня есть один первичный ключ и один 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);

Теперь, если любой идентификатор, accountId и dvrId существует в одном столбце, данные будут обновлены, в противном случае данные будут вставлены в новую строку.

Надеюсь, это поможет

person Radesh    schedule 22.05.2019
comment
Мне нужно обновить только несколько файлов в моей таблице, возможно ли это, используя ваш ответ? - person hio; 12.12.2019
comment
Спасибо. Я думаю, с этим нужно согласиться. - person Varun A M; 11.04.2021