当前位置: 首页 > 知识库问答 >
问题:

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

邢硕
2023-03-14

我需要更新,如果不存在插入行到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();
}

在道中:

@Insert
void insert(Product products);

但我有办法

@Update
void update(Product product);

我有一些问题:

>

  • 这两种方法都是无效的。如何在插入后返回保存的产品或布尔标志或插入计数?

    如何更新(如果没有-插入)行并返回count updatet或插入的行?


  • 共有3个答案

    尉迟墨竹
    2023-03-14

    您可以检查您的数据库是否已经有特定字段的项目,例如:

    @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)
                }
            }
    
    徐涵亮
    2023-03-14

    正如@Danail Alexiev所说的@Inert可以返回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")
      List<Product> getItemById(int id);
    
      @Query("UPDATE item SET quantity = quantity + 1 WHERE id = :id")
      void updateQuantity(int id)
    
      void insertOrUpdate(Product item) {
                    List<Product> itemsFromDB = getItemById(item.getId())
                    if (itemsFromDB.isEmpty())
                        insert(item)
                    else
                        updateQuantity(item.getId())   
                }
            }
    

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

    冯枫
    2023-03-14

    >

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

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

     类似资料:
    • 我用这个房间已经有一段时间了。我来自mysql的背景,您必须检查查询和其他内容的值。在room中,我发现这有点复杂,因为到目前为止,我可以将dao insert查询声明为void,或者只要返回rowId,如果返回long,我就必须编写一个侦听器来通知UI成功/失败。我的问题是,这是否必要?我是否需要insert/updates/deletes的返回值,或者这些查询是否保证成功?

    • 问题内容: 我在下面有一个SQL插入程序,它工作正常,但是我希望它检查DATE = xxxx,NAME = xxxx和JOB = xxx并更新HOURS(如果它们存在),否则插入新行。SQL可以做到这一点吗? 尝试以下具有相同结果的OR替换,每次都会添加一个新行。 例如: 如果以下内容位于数据库中,并且John要更新其工作时间,它将检查名称,日期,作业是否与尝试插入的值相同,并且它们是否仅更新HO

    • 问题内容: 我想向数据库表中添加一行,但是如果存在具有相同唯一键的行,我想更新该行。 例如: 假设唯一键为,并且在我的 数据库 中有一行。在这种情况下,我想用这些值更新该行。通常,这会产生错误。 如果使用它,将忽略该错误,但仍不会更新。 问题答案: 采用 查询:

    • 问题内容: 我正在尝试使用SQLAlchemy模块(而不是SQL!)在python中编写大量upsert。 我在SQLAlchemy添加上遇到以下错误: 我有一个称为列的主键的表。 在此示例中,我已经在数据库中使用了一行。当我尝试将新对象设置为时,出现上述错误。我的印象是,如果主键已经存在,记录将得到更新。 我如何仅基于主键就可以对Flask-SQLAlchemy进行增补? 有没有简单的解决方案?

    • 问题内容: 我有下表的计数器: 我想增加一个计数器,如果相应的行还不存在,则将其设置为零。有没有办法在标准SQL中没有并发问题的情况下做到这一点?该操作有时是事务的一部分,有时是独立的。 如果可能,SQL必须在SQLite,PostgreSQL和MySQL上未经修改地运行。 搜索产生了一些想法,这些想法可能遇到并发问题,或者特定于数据库: 尝试到新行,如果有错误。不幸的是,该错误会中止当前事务。

    • 问题内容: 我有一个带有2个表的数据库,如下所示: 列是,并且是 和 在申请表中,我有2个编辑框,名称分别为和 如果用户像电子邮件一样插入一个新的负责人姓名, 那么在保存表格的过程中,我想将新的负责人姓名插入表中,请插入最后一个并将其更新为。 如果用户保持名称,但它更新电子邮件一样,然后我想在从1 =使用新的电子邮件地址和他们(其余和)保持不变。 如果负责人的名称相同,我想保留from表的原始引用