【问题标题】:How to delete a List of Objects/Entities from room database?如何从房间数据库中删除对象/实体列表?
【发布时间】:2021-10-17 14:58:37
【问题描述】:

我想到了如何从 Room 数据库中删除单个实体或删除所有实体。但我想从房间数据库中删除一个实体列表,但没有找到任何解决方案。

我已经尝试过这些代码,但没有工作。

@Delete(entity = CollectionData.class)
void deleteList(List<CollectionData> collectionDataList);

@Delete
void deleteList(List<CollectionData> collectionDataList);

这些代码都不起作用。任何帮助...

【问题讨论】:

  • 它现在运行良好。我不知道以前有什么问题。但现在它在卸载并重新安装后工作正常。
  • 我做错的是在删除操作进行时修改列表,因为删除是通过执行程序服务在后台线程中运行的。所以传递一个复制的列表解决了我的问题。制作新列表:new ArrayList(listToBeDeleted)

标签: java android android-room


【解决方案1】:

你上面写的应该工作。你能回答以下问题吗?

  1. CollectionData 是否使用 @Entity 注释?
  2. 您是否为实体类定义了任何主键?
  3. 当您调用此删除方法时,请确保您传递的对象具有该主键。

你也可以发布你的实体类吗?

作为一种解决方法,您还可以执行以下操作:

@Query("delete from tableName where id in (:idList)")
fun deleteDataById(idList: List<Int>) 

【讨论】:

  • 嘿,感谢您对它的响应。
【解决方案2】:

有道没问题,所以很可能是你的列表不正确。人们容易陷入的一个陷阱是使用没有分配主键的对象,该对象在插入时生成主键时分配的值。

@PrimaryKey(autogenerate = true)
long the_variable_aka_columnname;
....
  • long 可以是 Long、int、Integer

类似的变体是

@PrimaryKey
Long the_variable_aka_columnname = null;
  • 长整数或整数

这两个结果都导致该列是 INTEGER PRIMARY KEY NOT NULL(前者具有 AUTOINCREMENT),这使该列成为 rowid 的别名,因此 Room 将不提供任何值,结果是该值将被分配。

因此,用于插入的对象与结果列不同,因此,如果用于删除,不会导致行被删除。

我怀疑这很可能是您没有提取@Primary Key 值的原因。

演示

@Entity CollectionData:-

@Entity
class CollectionData {
    @PrimaryKey
    Long id = null;
    String name;

    CollectionData(){}

    @Ignore
    CollectionData(String name) {
        this.name = name;
    }
}
  • 如果没有特别设置,id 列将被赋予一个值,类似于autogenerate = true

@Dao 类 CollectionDataDao :-

@Dao
abstract class CollectionDataDao {
    @Insert
    abstract long[] insert(ArrayList<CollectionData> collectionDataArrayList);
    @Delete
    abstract int delete(List<CollectionData> collectionDataList);
    @Query("SELECT * FROM collectiondata WHERE name LIKE :preWildChar||:nameSelection||:postWildChar")
    abstract List<CollectionData> getByName(String preWildChar, String nameSelection, String postWildChar);
    @Query("DELETE FROM collectiondata")
    abstract int deleteAll();
}

一个非常标准的@Database 类,因此无需包含(为了方便和简洁,请注意.allowManThreadQueries 已使用)。

还有一些活动中的代码,获取数据库和 dao,然后:-

  • 删除任何现有数据(以便于重新运行)
  • 创建一个 CollectionData 的 ArrayList (4)
  • 插入它们(获取 id 列表)
  • 写出 id 的列表
  • 写出 Arraylist,即 id 全部为空
  • 根据ArrayList写出删除次数删除
    • 0 因为没有 id 为 null 的行
  • 根据从数据库中获得的列表(带有各自的id)删除,写出删除的数字
    • 2 已删除,因为 id 与数据库中的内容匹配
  • 修改原始 ArrayList 将名称更改为未存储的名称,并通过插入的 id 将 id 更改为相应的 id。
  • 根据修改后的原列表删除,并写出删除的编号。
    • 剩下的 2 个。即上面插入的 4 个中的 2 个被删除,所以 2 个匹配。
    • 改名表示important值是id(主键),只有主键用于确定删除的内容。
    • 本质上Room构建SQLDELETE FROM the_table WHERE the_primary_key IN (the_list_of_primary_key_values_from_the_list_of_objects);

代码是:-

    db = TheDatabase.getInstance(this);
    daoCollectionData = db.getCollectionDataDao();
    daoCollectionData.deleteAll();
    ArrayList<CollectionData> cdl = new ArrayList();
    cdl.add(new CollectionData("CD001"));
    cdl.add(new CollectionData("CD002"));
    cdl.add(new CollectionData("CD003"));
    cdl.add(new CollectionData("CD0030"));
    /* Insert the Collection Datas  getting the IDs*/
    long[] insertedIdList = daoCollectionData.insert(cdl);
    /* Show the IDs (write to the log) */
    for(long l: insertedIdList) {
        Log.d("CDINFO","Insert ID = " + l);
    }
    /* The the original Collection Datas (null ID's) */
    for(CollectionData cd: cdl) {
        Log.d("CDINFO","Name = " + cd.name + " ID = " + cd.id);
    }
    /* DELETE according to original list. Note will not delete because IDs have not been set don't match */
    Log.d("CDINFO","CollectionData's deleted = " + daoCollectionData.delete(cdl));
    /* Extract some and delete (any with a 3 in the name)*/
    List<CollectionData> deleteList = daoCollectionData.getByName("%","3","%");
    Log.d("CDINFO"," CollectionData's deleted = " + daoCollectionData.delete(deleteList));
    /* alter the cdl list to set the ids */
    for (int i=0; i < insertedIdList.length; i++) {
        CollectionData replace = cdl.get(i);
        replace.id = insertedIdList[i];
        replace.name = "not the original name";
        cdl.set(i,replace);
    }
    /* Show the altered original list */
    for(CollectionData cd: cdl) {
        Log.d("CDINFO","Name = " + cd.name + " ID = " + cd.id);
    }
    /* and delete them */
    Log.d("CDINFO","CollectionData's deleted = " + daoCollectionData.delete(cdl));

日志的输出是:-

2021-10-18 22:37:18.295 D/CDINFO: Insert ID = 1
2021-10-18 22:37:18.295 D/CDINFO: Insert ID = 2
2021-10-18 22:37:18.295 D/CDINFO: Insert ID = 3
2021-10-18 22:37:18.295 D/CDINFO: Insert ID = 4
2021-10-18 22:37:18.295 D/CDINFO: Name = CD001 ID = null
2021-10-18 22:37:18.295 D/CDINFO: Name = CD002 ID = null
2021-10-18 22:37:18.295 D/CDINFO: Name = CD003 ID = null
2021-10-18 22:37:18.295 D/CDINFO: Name = CD0030 ID = null
2021-10-18 22:37:18.303 D/CDINFO: CollectionData's deleted = 0
2021-10-18 22:37:18.308 D/CDINFO:  CollectionData's deleted = 2
2021-10-18 22:37:18.308 D/CDINFO: Name = not the original name ID = 1
2021-10-18 22:37:18.308 D/CDINFO: Name = not the original name ID = 2
2021-10-18 22:37:18.308 D/CDINFO: Name = not the original name ID = 3
2021-10-18 22:37:18.308 D/CDINFO: Name = not the original name ID = 4
2021-10-18 22:37:18.311 D/CDINFO: CollectionData's deleted = 2
  • 您可能希望修改代码以将数据写入日志,这可能有助于查明您传递的列表有什么问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多