Android Room Database:如何嵌入多个实体
Posted
技术标签:
【中文标题】Android Room Database:如何嵌入多个实体【英文标题】:Android Room Database: How to embed multiple entities 【发布时间】:2019-01-22 10:55:39 【问题描述】:我正在为我的新项目使用空间,但我正在努力解决如何干净地访问一对一值
我有地址、所有者和网站的实体,所有者和网站都有关联的地址,每个网站都有一个所有者
是否可以干净地访问这些,例如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
)
道的
@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
【问题讨论】:
你的问题解决了吗? 你解决了吗? 【参考方案1】:您是否尝试过在您的实体之间建立关系? android Documentation for Relationships
@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。提供链接很好,但它是一个很好的做法,可以提供关于它如何回答最初问题的额外解释 添加了对应的代码sn-p,希望能澄清我的回答。【参考方案2】:您可以将 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
【讨论】:
以上是关于Android Room Database:如何嵌入多个实体的主要内容,如果未能解决你的问题,请参考以下文章
Android Room Database:如何处理实体中的 Arraylist?
获取 android 房间数据库 java.lang.IllegalArgumentException 的以下异常:@androidx.room.Database 未定义元素视图()