Android Room中的实体列表关系

Lyo*_*fen 5 database orm android kotlin android-room

我正在尝试加载实体子列表,但我想避免执行2个查询。

我正在考虑在TypeConverter中执行查询,但是我真的不知道这是否是个好主意。

我的实体:

@Entity
class Region(
        @PrimaryKey(autoGenerate = true)
        var id: Int = 0,
        var name: String = "",
        var locales: List<Locale> = listOf())

@Entity(foreignKeys = arrayOf(ForeignKey(
        entity = Region::class,
        parentColumns = arrayOf("id"),
        childColumns = arrayOf("regionId"),
        onDelete = CASCADE,
        onUpdate = CASCADE
)))
class Locale(
        @PrimaryKey(autoGenerate = true)
        var id: Int = 0,
        var regionId: Int = 0,
        var name: String = "")
Run Code Online (Sandbox Code Playgroud)

DAO:

@Dao
interface RoomRegionDao{
    @Insert
    fun insert(region: Region)

    @Delete
    fun delete(region: Region)

    @Query("select * from region")
    fun selectAll(): Flowable<List<Region>>
}

@Dao
interface RoomLocaleDao{
    @Insert
    fun insert(locale: Locale)

    @Query("select * from locale where regionId = :arg0")
    fun selectAll(regionId: Int): List<Locale>
}
Run Code Online (Sandbox Code Playgroud)

数据库:

@Database(entities = arrayOf(Region::class, Locale::class), version = 1)
@TypeConverters(RoomAppDatabase.Converters::class)
abstract class RoomAppDatabase : RoomDatabase() {
    abstract fun regionDao(): RoomRegionDao
    abstract fun localeDao(): RoomLocaleDao

    inner class Converters {
        @TypeConverter
        fun toLocales(regionId: Int): List<Locale> {
            return localeDao().selectAll(regionId)
        }

        @TypeConverter
        fun fromLocales(locales: List<Locale>?): Int {
            locales ?: return 0
            if (locales.isEmpty()) return 0

            return locales.first().regionId
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它不起作用,因为不能将内部类用作转换器类。

  • 这是个好方法吗?
  • 当我这样做时,如何自动在区域实体中加载“语言环境列表” RoomRegionDao.selectAll

Pie*_*ani 3

我认为这只TypeConverter适用于静态方法。我是根据这里这里的例子来这么说的

从这里的关系部分:

“因为 SQLite 是一个关系数据库,所以您可以指定对象之间的关系。尽管大多数 ORM 库允许实体对象相互引用,但 Room 明确禁止这样做。”

所以我想最好添加@Ignore你的属性并在插入locales上创建一个方法并在插入区域后调用它。RoomLocaleDaoList<Locale>

插入 Region 的方法可以返回插入的 id

如果@Insert方法只接收1个参数,它可以返回一个long,这是插入项的新rowId。如果参数是数组或集合,则应返回 long[] 或 List。(https://developer.android.com/topic/libraries/architecture/room.html#daos-convenience