Android Room Kotlin内部加入

时间:2018-03-15 17:25:59

标签: android kotlin android-room

我有两个实体 帐户:

@Entity(tableName = "accounts",foreignKeys = arrayOf(
        ForeignKey(
                entity = Currency::class,
                parentColumns = arrayOf("id"),
                childColumns = arrayOf("currencyId"),
                onDelete = ForeignKey.CASCADE
        )
))
data class Account (
        @PrimaryKey(autoGenerate = true)
        var id:Int=0,
        @ColumnInfo(name="name")
        var accountName:String,
        @ColumnInfo(name = "balance")
        var initialBalance:Double,
        var currencyId:Int,
        var date:Date,
        var isDefault:Boolean=true
){
    constructor():this(0,"",0.0,0,Date(),false)
}

和货币:

@Entity(tableName = "currencies")
data class Currency(
        @PrimaryKey(autoGenerate = true)
        var id:Int=0,
        @ColumnInfo(name="name")
        var currencyName:String,
        @ColumnInfo(name="code")
        var currencyCode:String
)
{
    constructor():this(0,"","")

    override fun toString(): String =currencyCode
}

我想在currency中嵌入account个对象。如您所见,我在currenciesaccounts之间存在一对多的关系。当我查询accounts实体时,我也想查看其货币。 我尝试在@Embedded实体中添加account字段,但它不起作用显然有一些我误解的内容,该字段返回null& #34;没有例外,只有null"。并且如果可能的话,"压扁" currency对象中的account对象,这会好得多。

所有这一切的要点是,我想在RecyclerView中显示所有帐户及其货币信息。我现在在@Embedded@Relation之间感到困惑,我们非常感谢任何帮助。

修改
我不知道这是否有帮助:
这是我的AccountDao

@Dao
interface AccountDao {
    @Insert
    fun insertAll(items:Array<Account>)

    @Update
    fun update(item:Account)

    @Delete
    fun delete(item:Account)

    @Query("select * from accounts")
    fun getAll():LiveData<Array<Account>>
}

2 个答案:

答案 0 :(得分:3)

我不会推荐上面的方法,因为你最终写了相同的属性(重复自己),也就是样板代码。

以下列方式使用@EmbeddedRelation注释,您的代码很可能如下所示:

data class AccountWithCurrency (
    @Embedded
    var account: Account? = null,
    @Relation(parentColumn = "id", entityColumn = "currencyId")
    var currency: List<Currency>? = null,
){
constructor() : this(Account(), emptyList())
}

答案 1 :(得分:1)

我设法让它发挥作用。解决方案是创建一个单独的(POJO或POKO无论如何)类,我称之为AccountModel

class AccountModel{
    var accountId:Int = 0
    var accountName:String = ""
    var accountInitialBalance:Double = 0.0
    var accountCreationDate: Date = Date()
    var currencyId:Int = 0
    var currencyCode:String = ""
    var isDefaultAccount:Boolean = false
    constructor()
    constructor(id:Int,name:String,balance:Double,date:Date,currencyId:Int,currencyCode:String,isDefault:Boolean){
        this.accountId = id
        this.accountName = name
        this.accountInitialBalance = balance
        this.accountCreationDate = date
        this.currencyId = currencyId
        this.currencyCode = currencyCode
        this.isDefaultAccount= isDefault
    }
    fun toAccount():Account = Account(this.accountId,this.accountName,this.accountInitialBalance,this.currencyId,this.accountCreationDate,this.isDefaultAccount)
}

然后,构建查询以执行正常inner join,就好像您正在为普通SQL数据库执行inner join一样。像这样:

@Query("select accounts.id as accountId," +
            "accounts.name as accountName," +
            "accounts.balance as accountInitialBalance," +
            "accounts.currencyId," +
            "accounts.date as accountCreationDate," +
            "accounts.isDefault as isDefaultAccount," +
            "currencies.code as currencyCode " +
            "from accounts inner join currencies on accounts.currencyId=currencies.id")
    fun getAll():LiveData<Array<AccountModel>>

显然,您可以使用as x将此列投影到返回对象中的x字段,正如您所知,在数据库中列为accounts.id但在我的{ {1}}它是AccountModel Google Room的真正令人印象深刻的事情是,虽然我添加了一个非常聪明的accountId对象,但我能够得到LiveData AccountModel