【问题标题】:Retrofit to Room models mapping改造到房间模型映射
【发布时间】:2019-09-12 09:43:02
【问题描述】:

我有一个问题可能对你们中的一些人来说很容易,但我真的无法解决。

我有一个格式如下的 json:

{
    "id" : "1641S818",
    "balance" : "100.20",
    "transactions" : [
        {
            "id" : "item1",
            "price" : "1.50",
            "description" : "pen",
            "date" : "2018-05-14T14:19:00Z"
        },
        {
            "id" : "item1",
            "price" : "9.00",
            "description" : "book",
            "date" : "2018-05-14T08:19:00Z"
        }
    ]
}

我想第一次尝试使用 Retrofit + Room 构建应用,但在构建模型时遇到了麻烦。

我想出了这个用于 Retrofit 的数据类,它们运行良好。这并不奇怪,因为我知道如何使用它。

data class Account (
    val id : String,
    val balance : Double,
    val transactions : List<Transaction>
)

data class Transaction (
    val id : String,
    val price : Double,
    val description : String,
    val date : String
)

当我想将这个结构保存在数据库中时,真正的问题就开始了,账户和交易之间存在这种一对多的关系。到目前为止,我了解到 Room 无法处理这种类型的结构,我应该为数据库模型构建不同的类。所以我做了:

@Entity(tableName = "account")
data class AccountData(

    @ColumnInfo(name = "id")
    @PrimaryKey(autoGenerate = false)
    val id: String,

    val balance: Double,

)

@Entity(
    tableName = "transaction",
    foreignKeys = [
        ForeignKey(
            entity = AccountData::class,
            parentColumns = ["id"],
            childColumns = ["account_id"],
            onUpdate = ForeignKey.CASCADE,
            onDelete = ForeignKey.CASCADE
        )
    ]
)
data class TransactionData(

    @PrimaryKey(autoGenerate = false)
    @ColumnInfo(name = "id")
    val transactionId: String,

    @ColumnInfo(name = "account_id")
    val accountId: String,

    val price: Double,

    val description: String,

    val date: String

)

现在是我卡住的部分。在这种特殊情况下,当我们在对象之间存在复杂关系而不仅仅是普通类时,我找不到任何指南、示例、任何显示在何处使用映射器(可能使用 livedata 或 rx)转换模型的东西。

【问题讨论】:

    标签: android mapping retrofit retrofit2 android-room


    【解决方案1】:

    您可以使用这样的扩展功能定义单独的 Mapper 文件

    fun Transaction.toTransactionData() = TransactionData(...)
    

    然后在 API 调用之后,可能在 UseCase 中,您可以使用此函数将您的 API 实体映射到 DB 实体,然后将结果传递给 Room dao。

    UPD 1。 此外,您可以为 UI 使用定义 Transation 实体。因此,在 UseCase 级别,您使用 RestTransactionDbTransaction 进行操作,但将 Transaction 传递给 UI,以从其源代码中抽象出来。

    【讨论】:

    • 谢谢我的朋友。我会尝试实现这一点,并会让你知道。我仍然有点困惑,但我想这样做会为我清除问题。有一个示例会有所帮助,但似乎我在 github 上找到的每个“游乐场”应用程序和每个 google 示例都只展示了最简单的案例。
    • github.com/Ufkoku/Dagger2.Android-Arch.Components 你可以查看我的仓库。它没有 DB,但有单独的 UI 和 REST 实体
    • 我忘了更新这个帖子,但这非常有用,现在它是我一直使用的标准方法。
    猜你喜欢
    • 1970-01-01
    • 2021-01-03
    • 2018-11-07
    • 1970-01-01
    • 2020-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多