房间更新(或插入,如果不存在)行和返回计数更改行

时间:2018-01-30 11:06:45

标签: android android-room

我需要更新,如果不存在,则将行插入ROOM DB。

我这样做:productRepository.updateProducts(productsResponse.getProductItems());

@Override
public void updateProducts(final List<ProductItem> products) {
    new Thread(() -> {
        for (ProductItem item : products) {
            Product product = createProduct(item);
            productDao.insert(product);
        }
    }).start();
}

在DAO中:

@Insert
void insert(Product products);

但我有方法

@Update
void update(Product product);

我有一些问题:

  1. 两种方法均无效。如何在插入后返回保存的Product或布尔标志或插入的计数?

  2. 如果我尝试拨打update并且我没有插入会插入吗?

  3. 如何更新(如果不是 - 插入)行并返回计数更新或插入行?

6 个答案:

答案 0 :(得分:24)

  1. 使用@Insert注释的方法可以返回long。这是插入行的新生成的ID。使用@Update注释的方法可以返回int。这是更新行的数量。

  2. update将尝试使用where子句中主键的值更新所有字段。如果您的实体尚未保留在数据库中,update查询将无法找到行并且不会更新任何内容。

  3. 您可以使用@Insert(onConflict = OnConflictStrategy.REPLACE)。这将尝试插入实体,如果存在具有相同ID值的现有行,它将删除它并将其替换为您尝试插入的实体。请注意,如果您使用自动生成的ID,则意味着生成的行将具有与替换的原始ID不同的ID。如果你想保留ID,那么你必须想出一个自定义的方法。

答案 1 :(得分:4)

已经有一段时间了,但是这个问题没有一个可以接受的答案,所以我会考虑一下。

正如@Danail Alexiev所说@Insert可以返回long@Update可以返回int

但是您出于什么目的使用更新?如果您只想将整个对象替换为新对象,则只需指定OnConflictStrategy

@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Product products);

结果将是::将添加不存在的项目,将已存在的项目替换为新项目。

如果您只需要更新一个参数(例如数量),则可以执行以下操作

  @Insert(onConflict = OnConflictStrategy.REPLACE)
  void insert(Product products);

  @Query("SELECT * from item WHERE id= :id")
  void getItemById(int id): List<Product>

  @Query("UPDATE item SET quantity = quantity + 1 WHERE id = :id")
  void updateQuantity(int id)

  void insertOrUpdate(Product item) {
                Product itemFromDB = getItemById(item.getId())
                if (itemFromDB == null)
                    insert(item)
                else
                    updateQuantity(item.getId())
            }
        }

结果将是::尝试在数据库中查找项目,如果发现更新属性,则不只是插入新项目。因此,您只需要从DAO调用一种方法insertOrUpdate

答案 2 :(得分:3)

如果已存在具有特定字段的项目,您可以检查数据库,例如:

@Query("SELECT id FROM items WHERE id = :id LIMIT 1")
fun getItemId(id: String): String?

@Insert
fun insert(item: Item): Long

@Update(onConflict = OnConflictStrategy.REPLACE)
fun update(item: Item): Int

项目是您的对象,在您的代码中:

 fun insertOrUpdate(item: Item) {
            database.runInTransaction {
                val id = getItemDao().getItemId(item.id)

                if(id == null)
                    getItemDao().insert(item)
                else
                    getItemDao().update(item)
            }
        }

答案 3 :(得分:0)

您可以检查下面的方法insertModel(),在其中可以获取onComplete()和onError()方法:

    val db: AppDatabase = Room.databaseBuilder(mCtx, AppDatabase::class.java, "db_nam.sqlite").build()

    companion object {
        @SuppressLint("StaticFieldLeak")
        private var mInstance: DatabaseClient? = null

        @Synchronized
        fun getInstance(mCtx: Context): DatabaseClient {
            if (mInstance == null) {
                mInstance = DatabaseClient(mCtx)
            }
            return mInstance as DatabaseClient
        }
    }

    // SEE HERE FOR INSERTING DATA SUCCESSFULLY AND ERROR CODE  
    private fun insertModel(rss_Model: RSS_Model) {
        Completable.fromAction {

            db.database_dao().insertRSS(rss_Model)

        }.observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io()).subscribe(object : CompletableObserver {
                    override fun onSubscribe(d: Disposable) {}

                    override fun onComplete() {
                        // Log.e("onComplete","GET SUCCESS HERE")
                    }

                    override fun onError(e: Throwable) {
                        // Log.e("onError","onError")
                    }
                })
    }

答案 4 :(得分:-1)

您应该使用Rx Android Single 解决此问题。示例:

@Query("SELECT * FROM subjectFormTable WHERE study_subject_id ==:subjectFormId")
fun getSubjectForm(subjectFormId: Int): Single<SubjectFormEntity>

我们使用

val compositeDisposable = CompositeDisposable()

compositeDisposable.add(
            subjectFormDao.getSubjectForm(studySubjectId)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                Log.e(TAG, "successful ")
            }, {
                Log.e(TAG, "error "+it.message)
                //Insert or Update data here
            })
    )

答案 5 :(得分:-1)

您还可以检查该条目是否存在于数据库中,您可以据此做出逻辑

科特林

@Query("SELECT * FROM Product WHERE productId == :id")
fun isProductExist(id: Int): Boolean

Java

@Query("SELECT * FROM Product WHERE productId == :id")
public boolean isExist(int id);