Android Room Database 执行批量更新的正确语法是什么?
Android Room Database what is the correct syntax to perform bulk update?
我正在做一个项目,其中有一个名为 Messages(uuid, body, metadata_list, ... ...)
的 table,我想对 message_body 和 metadata_list 列执行批量更新。我关注了 this answer.
我创建了一个数据class
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<MyTuple>
,修改了它,现在我想在 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<MyTuple>
,让 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)) ...”部分出错。那么使用房间进行批量更新的正确语法是什么?
@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 方法,从长远来看,它很可能会为您提供更好的服务 运行。
我正在做一个项目,其中有一个名为 Messages(uuid, body, metadata_list, ... ...)
的 table,我想对 message_body 和 metadata_list 列执行批量更新。我关注了 this answer.
我创建了一个数据class
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<MyTuple>
,修改了它,现在我想在 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<MyTuple>
,让 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)) ...”部分出错。那么使用房间进行批量更新的正确语法是什么?
@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 方法,从长远来看,它很可能会为您提供更好的服务 运行。