You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Room数据库中如何通过legalName字段查询Person实体对象?

解决Room数据库中通过嵌套对象字段查询的问题

问题原因

Room默认不会自动解析嵌套的数据类字段,你的Person实体中name是Name类型的嵌套对象,数据库表中并不会生成name.legalName这样的层级列,因此直接用该语法查询会报错。

方案一:使用@Embedded注解展开嵌套字段(推荐)

通过@Embedded注解,Room会将嵌套对象的字段直接映射为数据库表的列,这样就能直接通过legalName字段查询。

修改实体类:

@Entity
data class Person(
    @Embedded val name: Name,
    // 其他字段...
)

data class Name(
    val legalName: String,
    val common: String
)

修改DAO查询语句:

@Query("SELECT * FROM person WHERE legalName = :legalName")
suspend fun getPersonByName(legalName: String): Person?

方案二:使用TypeConverter存储JSON格式(备选)

如果需要保留嵌套对象的结构,可以通过TypeConverter将Name转换为JSON字符串存储,再用SQL的JSON函数查询(仅支持Android API 26及以上)。

  1. 编写TypeConverter类:
class NameConverter {
    private val gson = com.google.gson.Gson()

    @androidx.room.TypeConverter
    fun fromName(name: Name): String = gson.toJson(name)

    @androidx.room.TypeConverter
    fun toName(nameJson: String): Name = gson.fromJson(nameJson, Name::class.java)
}
  1. 在Room数据库类中注册转换器:
@androidx.room.Database(entities = [Person::class], version = 1)
@androidx.room.TypeConverters(NameConverter::class)
abstract class AppDatabase : androidx.room.RoomDatabase() {
    abstract fun personDao(): PersonDao
}
  1. 修改查询语句:
@Query("SELECT * FROM person WHERE JSON_EXTRACT(name, '$.legalName') = :legalName")
suspend fun getPersonByName(legalName: String): Person?

注意事项

  • 方案一性能更优,且兼容性更好,优先选择。
  • 如果存在多个嵌套对象可能导致列名冲突,可以给@Embedded添加prefix参数,比如@Embedded(prefix = "name_"),此时查询字段变为name_legalName。

内容的提问来源于stack exchange,提问作者Chris Shafer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 01:15:32