room update (or insert if not exist) rows and return count changed rows
我需要更新,如果不存在,请向ROOM DB插入行。
我这样做:
和:
1 2 3 4 5 6 7 8 9 | @Override public void updateProducts(final List<ProductItem> products) { new Thread(() -> { for (ProductItem item : products) { Product product = createProduct(item); productDao.insert(product); } }).start(); } |
在DAO中:
1 2 | @Insert void insert(Product products); |
但是我有方法
1 2 | @Update void update(Product product); |
我有一些问题:
两种方法均无效。 插入后如何返回已保存的Product或boolean标志或插入的计数?
如果我尝试调用
如何更新(如果不是-插入)行并返回计数更新或插入的行?
用
您可以使用
已经有一段时间了,但是这个问题没有一个可以接受的答案,所以我会考虑一下。
正如
但是,您出于什么目的使用更新?如果只想用新对象替换整个对象,则只需指定
1 2 | @Insert(onConflict = OnConflictStrategy.REPLACE) void insert(Product products); |
结果将是:将添加不存在的项目,将已存在的项目替换为新项目。
如果您只需要更新一个参数(例如数量),则可以执行以下操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @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调用一种方法
您可以检查数据库是否已存在具有特定字段的项目,例如:
1 2 3 4 5 6 7 8 | @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 |
Item是您的对象,并且在您的代码中:
1 2 3 4 5 6 7 8 9 10 | fun insertOrUpdate(item: Item) { database.runInTransaction { val id = getItemDao().getItemId(item.id) if(id == null) getItemDao().insert(item) else getItemDao().update(item) } } |
您可以在下面的方法insertModel()中进行检查,可以在其中获取onComplete()和onError()方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | 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") } }) } |
您应该使用Rx Android Single来解决此问题。例:
1 2 | @Query("SELECT * FROM subjectFormTable WHERE study_subject_id ==:subjectFormId") fun getSubjectForm(subjectFormId: Int): Single<SubjectFormEntity> |
我们用
1 | val compositeDisposable = CompositeDisposable() |
和
1 2 3 4 5 6 7 8 9 10 11 | 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 }) ) |