Android Room Database 执行批量更新的正确语法是啥?

Posted

技术标签:

【中文标题】Android Room Database 执行批量更新的正确语法是啥?【英文标题】:Android Room Database what is the correct syntax to perform bulk update?Android Room Database 执行批量更新的正确语法是什么? 【发布时间】:2021-12-20 11:27:23 【问题描述】:

我正在处理一个项目,其中有一个名为 Messages(uuid, body, metadata_list, ... ...) 的表,我想对 message_body 和 metadata_list 列执行批量更新。我关注了this answer。

我创建了一个数据类


MyTuple(    
    @ColumnInfo(name = "uuid") var uuid: String,
    @ColumnInfo(name = "body") var body: SpannableStringBuilder,
    @ColumnInfo(name = "mention_metadata_list") var mentionMetaDataList: List<MentionsMetaData>? = ArrayList<MentionsMetaData>()
)

然后我查询这些列,得到一个list: List&lt;MyTuple&gt;,修改它,现在我想在sqlite数据库中批量更新这些新值。

我卡住了,所以创建了一个这样的 SimpleSQLiteQuery 对象:

String rawSqlInput = "(1, 'foo1', ''bar1), (2, 'foo2', 'bar2')"; // generated using for loop.

String rawQuery = "WITH temp_table(id, new_body, mmd_list)  AS  (VALUES" + rawSqlInput + ")  UPDATE messages SET body = (SELECT new_body FROM temp_table WHERE temp_table.id == messages.uuid), mention_metadata_list = (SELECT mmd_list FROM temp_table WHERE temp_table.id == messages.uuid) WHERE uuid IN (SELECT id FROM TEMP_TABLE)";

SimpleSQLiteQuery simpleSQLiteQuery = new SimpleSQLiteQuery(rawQuery);
mChatDao.bulkUpdateBodyAndMetaDataForGroupMessages(simpleSQLiteQuery);  // this one works fine

而我的道是这样的:

@Dao
abstract class ChatDao 
    @RawQuery
    abstract fun bulkUpdateBodyAndMetaDataForGroupMessages(query: SimpleSQLiteQuery): Int;

这没问题。

问题

我不想创建rawSqlInput 变量,并使用上面的simpleSQLiteQuery。相反,我想在 dao 方法中传递 list: List&lt;MyTuple&gt;,让 room 为我处理一切。

我试过了,但失败了:

@Dao
abstract class ChatDao 
@Query("WITH temp_table(id, new_body, mmd_list)  AS (VALUES (:mmdTuples))  UPDATE messages SET body = (SELECT new_body FROM temp_table WHERE temp_table.id == messages.uuid), mention_metadata_list = (SELECT mmd_list FROM temp_table WHERE temp_table.id == messages.uuid) WHERE uuid IN (SELECT id FROM TEMP_TABLE)")
abstract fun bulkUpdateBodyAndMetaDataForGroupMessages(mmdTuples: List<MyTuple>)


但它没有工作。我在“...AS (VALUES(:mmdTuples)) ...”部分出现错误。那么使用 room 进行批量更新的正确语法是什么?

【问题讨论】:

【参考方案1】:
@Update
abstract fun update(myTuple : MyTuple)

//This function is under a transaction so it will be commited to the database
//all at the same time.
@Transaction
fun update(list : List<MyTuple>)
   list.forEach
      update(it)
   

这只是处理它的一种方法,但您可以采用 upsert 方法,从长远来看很可能会为您提供更好的服务。 android Room Persistence Library: Upsert

【讨论】:

以上是关于Android Room Database 执行批量更新的正确语法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Android Room Database 学习

Android Room Database:如何处理实体中的 Arraylist?

获取 android 房间数据库 java.lang.IllegalArgumentException 的以下异常:@androidx.room.Database 未定义元素视图()

添加1到多关系android Room Database?

Android Room Database,检索输入的最新记录的特定值

Android Room Database:如何嵌入多个实体