我想在我的Room数据库中保存一个对象,其中一个变量可以是on类型,也可以是其他类型。我认为一个sealed类是有意义的,所以我采用了这种方法:
sealed class BluetoothMessageType() {
data class Dbm(
val data: String
) : BluetoothMessageType()
data class Pwm(
val data: String
) : BluetoothMessageType()
}
或者甚至是这个,但这是没有必要的。我发现这个给了我更多的错误,因为它不知道如何处理开放的瓦尔,所以如果我找到了第一个版本的解决方案,我会很高兴无论如何。
sealed class BluetoothMessageType(
open val data: String
) {
data class Dbm(
override val data: String
) : BluetoothMessageType()
data class Pwm(
override val data: String
) : BluetoothMessageType()
}
然后是Entity类
@Entity(tableName = MESSAGES_TABLE_NAME)
data class DatabaseBluetoothMessage(
@PrimaryKey(autoGenerate = true)
val id: Long = 0L,
val time: Long = Instant().millis,
val data: BluetoothMessageType
)
我已经创建了一个TypeConverter来将它与String进行转换,所以我认为这不是一个问题。
首先,这是可能的吗?我假设它应该以类似于抽象类的方式工作,但我也没有设法找到一个工作的解决方案。如果这是不可能的,当我想保存一些数据时,如果不是用密封类,我应该采取什么样的方法?
2条答案
按热度按时间lsmd5eda1#
当我们尝试在我们的领域中使用多态性时,我们遇到了这样的问题,我们这样解决了它:
网域:
我们有一个
Photo
模型,如下所示:Photo
内部包含PhotoSize
,看起来如下:数据:
要实现这一点,我们的数据模块中有很多工作要做。为了使它看起来更简单,我将把这个过程分解为三个部分:
1.实体:
因此,一般使用Room和SQL,很难保存这样的对象,所以我们不得不提出这个想法。我们的
PhotoEntity
(这是我们域中Photo
的本地版本,看起来像这样:我们的
PhotoSizeEntity
如下所示:然后,我们使用这个复合类将
PhotoEntity
和PhotoSizeEntity
合并在一起,这样我们就可以检索域模型所需的所有数据:2.刀
因此我们的
dao
应该能够存储和检索这些数据。为了灵活起见,您可以有两个daos
(用于PhotoEntity
和PhotoSizeEntity
),而不是一个,但在本例中,我们将使用一个共享的daos
,如下所示:3.适配器:
在解决了将数据保存到SQL数据库的问题之后,我们现在需要解决域和本地实体之间的转换问题,我们的
Photo
的转换器aka适配器看起来像这样:对于
PhotoSize
,它看起来像这样:就是这样!
结论:
要将一个密封类保存到Room或SQL中,无论是作为
Entity
还是作为Embedded
对象,您都需要有一个大数据类,其中包含所有密封变量的所有属性,并使用Enum
类型来指示变量类型,以便以后在域和数据之间进行转换时使用,或者如果您不使用Clean Architecture,则在代码中进行指示。但是坚实而灵活。我希望Room
将有一些注解,可以生成这样的代码,以摆脱样板代码。PS:这个类取自Telegram的scheme,他们也解决了与服务器通信时的多态性问题。在这里查看他们的TL语言:https://core.telegram.org/mtproto/TL
PS2:如果你喜欢Telegram的TL语言,你可以使用这个生成器从
scheme.tl
文件生成Kotlin类:https://github.com/tamimattafi/mtproto**EDIT:**您可以使用此代码生成库自动为复合类生成Dao,使其更易于插入,从而删除了大量的样板文件以正确Map内容。链接:https://github.com/tamimattafi/android-room-compound
快乐编码!
11dmarpk2#
在我的案例中,我做了以下操作:
它就像一个符咒