更新子 table 房间数据库中的参数

Update parameter inside child table room database

我需要帮助。我需要更新 ConnectionWithPassenger 中的 lastStatus,它是 LocalConnectionsNearbyList 列表的一部分。如果我尝试用我的构建失败的第一个查询更新它,我会得到一个错误:“查询有问题:[SQLITE_ERROR] SQL 错误或缺少数据库(没有这样的 table: single_connection)”。什么是有意义的。但是我也不能用第二个查询来更新它。我收到另一个错误:“在输入 'UPDATE connections_new WHERE' public abstract void updateOut(@org.jetbrains.annotations.NotNull()) 处没有可行的替代方案”。我不想更改数据库结构。提前感谢任何想法。

@TypeConverters(ConnectionConverter::class)
@Entity(tableName = "connections_new")
data class LocalConnectionsNearbyList(
    @PrimaryKey
    var rideId: String,
    var connectionsWithPassengers: MutableList<ConnectionWithPassenger>,
)

@Entity(tableName = "single_connection")
data class ConnectionWithPassenger(
    @PrimaryKey
    val serverId: String,
    var connectionIdNearBy: String,
    var lastStatus: String,
    var lastTimeStamp: Long,
    var isSent: Boolean,
    var name:String,
    var image:String
)

数据库:

@Database(
    entities = [
....
        LocalConnectionsNearbyList::class
    ], version = 2, exportSchema = false
)

查询思路1:

 @Query("UPDATE single_connection SET lastStatus=:lastStatus WHERE connectionIdNearBy LIKE :lastStatus")
 fun updateOut(idOfConnection:String, lastStatus:String)

查询思路2:

@Query("UPDATE connections_new WHERE rideId=:id SET lastStatus=:lastStatus WHERE connectionIdNearBy LIKE :lastStatus")
fun updateOut(idOfConnection:String, lastStatus:String)

第一个查询不起作用,因为您可能没有将 ConnectionWithPassenger 实体定义为 entities = [] 中的实体,在 class 中注释为 [=18] =].

  • 如果不是,@Entity 注释是无用的 (甚至 damaging/frustating,因为它允许您像 table 一样编写 single_connection.

第二个查询试图引用不在 connections_new table 中的列。 table 只有两列 rideIdconnectionsWithPassengers.

connectionsWithPassengers 列中保存的数据很可能包含 lastStatus 值(取决于 TypeConverter)但 lastStatus 不是列(同样对于connectionIdNearBy 列)。

使用你所拥有的,你必须:-

  • 找到并更改 connectionsWithPassengers 列中的值(SQL 明智的做法可能是一场噩梦,但取决于 TypeConverter,因为 TypeConverter 决定了数据在列中的保存方式),或
  • 提取 connectionsWithPassengers 列表,然后 extract/locate 从列表中提取相应的 connectionsWithPassengers 对象,然后使用修改后的 connectionsWithPassengers 对象列表更新列。

例子

在此示例中,它们在很大程度上取决于 TypeConverters:-

@TypeConverter
fun fromConnectionWithPassengerListHolder(cwplh: ConnectionWithPassengerListHolder): String {
    return Gson().toJson(cwplh)
}
@TypeConverter
fun toConnectionWithPassengerListHolder(json: String): ConnectionWithPassengerListHolder {
    return Gson().fromJson(json,ConnectionWithPassengerListHolder::class.java)
} 

已添加新的 class ConnectionWithPassengerListHolder,因为您在尝试使用 var connectionsWithPassengers: MutableList<ConnectionWithPassenger>

时遇到问题

所以 ConnectionWithPassengerListHolder 是 :-

data class ConnectionWithPassengerListHolder (
    val connectionWithPassengerList: MutableList<ConnectionWithPassenger>
    )

哟利用上面的LocalConnectionsNearbyList已经改成:-

@TypeConverters(ConnectionConverter::class)
@Entity(tableName = "connections_new")
data class LocalConnectionsNearbyList(
    @PrimaryKey
    var rideId: String,
    //var connectionsWithPassengers: MutableList<ConnectionWithPassenger>,
    var connectionsWithPassengers: ConnectionWithPassengerListHolder
)

AllDao抽象class(而不是接口):-

@Dao
abstract class AllDao {

    @Insert(onConflict = IGNORE)
    abstract fun insert(localConnectionsNearbyList: LocalConnectionsNearbyList): Long

    @Query("SELECT * FROM connections_new WHERE rideId=:rideId")
    abstract fun getNewConnectionByRideId(rideId: String): LocalConnectionsNearbyList

    @Update
    abstract fun update(localConnectionsNearbyList: LocalConnectionsNearbyList): Int

    @Query("")
    @Transaction
    fun updateLastStatusOfConnectionNearby(rideId: String, connectionNearBy: String, newStatus: String) {
        var update_needed = false
        var lcnl: LocalConnectionsNearbyList = getNewConnectionByRideId(rideId)
        for (cwp: ConnectionWithPassenger in lcnl.connectionsWithPassengers.connectionWithPassengerList) {
            if (cwp.connectionIdNearBy == connectionNearBy) {
                cwp.lastStatus = newStatus
                update_needed = true
            }
        }
        if (update_needed) {
            update(lcnl)
        }
    }
}

和 activity 中的以下内容(.allowMainThreadQueries 在构建数据库时用于简洁)

    db = TheDatabase.getInstance(this)
    dao = db.getAllDao()

    var lc1 = LocalConnectionsNearbyList("ride1",
        ConnectionWithPassengerListHolder(
            mutableListOf(
                ConnectionWithPassenger("S1","n1","NEW",0,false,"Fred","i1"),
                ConnectionWithPassenger("S2","n2","NEW",0,false,"Mary","i2"),
                ConnectionWithPassenger("S3","n3","NEW",0,false,"Jane","i3"),
                ConnectionWithPassenger("S4","n4","NEW",0,false,"Tom","i4")
            )
        )
    )
    dao.insert(lc1)
    dao.updateLastStatusOfConnectionNearby(lc1.rideId,"n3","CHANGED")
    dao.updateLastStatusOfConnectionNearby(lc1.rideId,"n1","ALTERED")

}

这将:-

  1. 获取数据库实例
  2. 获取AllDao实例
  3. 向数据库添加一个 LocalConnectionsNearbyList 和 4 ConnectionsWithPassengers(注意 ConnectionWithPassengerListHolder 是为了避免对列使用 List/Array)。
  4. 将数据库中第 3 个 ConnectionWithPassenger 的 lastSatatus 从 NEW 更改为 CHANGED
  5. 在数据库中将第一个 ConnectionWithPassenger 的 lastSatatus 从 NEW 更改为 ALTERED

注意以上是designed/intended到运行只有一次。

结果

在 运行 上面的例子然后使用 Android Studio 的 App Inspection :-

可以看出,connectionsWithPassengers中的数据并未全部显示出来。复制数据显示数据为 :-

{"connectionWithPassengerList":[
    {"connectionIdNearBy":"n1","image":"i1","isSent":false,"lastStatus":"ALTERED","lastTimeStamp":0,"name":"Fred","serverId":"S1"},
    {"connectionIdNearBy":"n2","image":"i2","isSent":false,"lastStatus":"NEW","lastTimeStamp":0,"name":"Mary","serverId":"S2"},
    {"connectionIdNearBy":"n3","image":"i3","isSent":false,"lastStatus":"CHANGED","lastTimeStamp":0,"name":"Jane","serverId":"S3"},
    {"connectionIdNearBy":"n4","image":"i4","isSent":false,"lastStatus":"NEW","lastTimeStamp":0,"name":"Tom","serverId":"S4"}
    ]
}
  • 请注意,数据已使用换行符和制表符拆分,以使其更直观table。

  • 可以看出,第一个 connectionWithPassengers 的 lastStatus 已更改为 ALTERED,第三个已更改为 CHANGED 其他两个不变为 NEW.