Android Room数据库:如何嵌入多个实体

13

我正在使用Room技术开展我的新项目,但我在如何清晰地访问一对一的值方面遇到了困难。


我有关于地址、所有者和站点的实体,所有者和站点都有一个相关联的地址,每个站点都有一个所有者。


是否可以方便地访问这些内容,例如site.owner.address.l1

我尝试过使用@Relation,但它返回一个列表,这不是理想的解决方案。

实体

@Entity(tableName="addresses")
data class Address(
    @PrimaryKey
    @ColumnInfo(name="address_id")
    val id: Int,

    @ColumnInfo(name="address_l1")
    val l1: String
)

@Entity(tablename="owners")
data class Owner(
    @PrimaryKey
    @ColumnInfo(name="owner_id")
    val id: Int,

    @ColumnInfo(name="owner_name")
    val name: String
)

@Entity(tableName="sites")
data class Site(
    @PrimaryKey
    @ColumnInfo(name="site_id")
    val id: Int,

    @ColumnInfo(name="site_addressid")
    val addressid: Int

    @ColumnInfo(name="site_ownerid")
    val ownerid: Int
)

Dao的

@Query("SELECT * FROM sites")
fun getSites(): List<Site>

@Query("SELECT * FROM owners")
fun getOwners(): List<Owner>

@Query("SELECT * FROM addresses")
fun getAddresses(): List<Address>

@Query("SELECT * FROM sites JOIN address ON sites.site_addressid = address.address_id JOIN owners ON sites.site_ownerid = owners.owner_id JOIN address ON owners.owner_addressid = address.address_id WHERE sites.site_id = :siteid")
fun getSiteByIdWithDetails(siteid): Site

我只能看到使用多个POJO的方法使其工作,例如
不是有效但大致正确


data class OwnerAddress(
    @Embedded
    val owner: Owner,

    @Embedded
    val address: Address
)

data class SiteAddress(
    @Embedded
    val site: Site,

    @Embedded
    val owner: OwnerAddress,

    @Embedded
    val address: Address
}

并通过它使用

@Query("SELECT * FROM sites JOIN address ON sites.site_addressid = address.address_id JOIN owners ON sites.site_ownerid = owners.owner_id JOIN address ON owners.owner_addressid = address.address_id WHERE sites.site_id = :siteid")
fun getSiteByIdWithDetails(siteid): SiteAddress

你解决了你的问题吗? - the_dani
你解决了吗? - Farhan Ibn Wahid
2个回答

0
你可以使用TypeConverter和Gson库来处理你的作用域。
将你的数据类定义为:
@Entity(tableName="addresses")
data class Address(
    @PrimaryKey
    @ColumnInfo(name="address_id")
    val id: Int,

    @ColumnInfo(name="address_l1")
    val l1: String
)

@Entity(tablename="owners")
data class Owner(
    @PrimaryKey
    @ColumnInfo(name="owner_id")
    val id: Int,

    @ColumnInfo(name="owner_name")
    val name: String
)

@Entity(tableName="sites")
data class Site(
    @PrimaryKey
    @ColumnInfo(name="site_id")
    val id: Int,

    @ColumnInfo(name="site_address")
    val address: Address,

    @ColumnInfo(name="site_owner")
    val owner: Owner
)

然后创建一个DatabaseConverter

class DatabaseConverter 
{
    @TypeConverter
    fun ownerFromJson(jsonString: String) : Owner {
        val ownerType = object : TypeToken<Owner>() { }.type
        return Gson().fromJson(jsonString, ownerType)
    }

    @TypeConverter
    fun jsonFromOwner(owner: Owner) : String = Gson().toJson(owner)

    @TypeConverter
    fun addressFromJson(jsonString: String) : Address {
        val addressType = object : TypeToken<Address>() { }.type
        return Gson().fromJson(jsonString, addressType)
    }

    @TypeConverter
    fun jsonFromAddress(address: Address) : String = Gson().toJson(address)
}

然后将其附加到您的RoomDatabase实例类上

@Database(entities = [ ... ], version = ...)
@TypeConverters(DatabaseConverter::class)
abstract class YourDatabaseClass: RoomDatabase() {
    ...
}

现在,您应该能够使用以下方式访问您的子实体实例:

site.site_address.id 
site.site_owner.id

0

你尝试过在实体之间建立关系吗?Android 关系文档

@Entity(tableName="addresses")
data class Address(
    @PrimaryKey
    @ColumnInfo(name="address_id")
    val id: Int,

    @ColumnInfo(name="address_l1")
    val l1: String
)

@Entity(tablename="owners")
data class Owner(
    @PrimaryKey
    @ColumnInfo(name="owner_id")
    val id: Int,

    @ColumnInfo(name="owner_name")
    val name: String

    @ColumnInfo(name="owner_adress")
    @Entity val adress: Address
)

@Entity(tableName="sites")
data class Site(
    @PrimaryKey
    @ColumnInfo(name="site_id")
    val id: Int,

    @ColumnInfo(name="site_owner")
    @Embedded val owner: Owner

    @ColumnInfo(name="site_address")
    @Embedded val address: Address
)

现在你的网站有一个地址和一个所有者(其也有自己的地址)。你的sites表和owners表都将包含地址列。


你好,欢迎来到SO。提供链接是可以的,但最好还要额外解释一下它如何回答初始问题,这是一个好习惯。 - bagerard
2
已添加相应的代码片段,希望能够澄清我的回答。 - ilkeraslan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接