如何在 Room 中查询复杂的嵌套对象?
How to query a complex nested objects in Room?
我有几个实体,您可以在下面看到,问题是当您有多于一层的嵌套时如何正确 select 嵌套列表。如果您查看 github, you can find very simple example, but not something complex. As documentation says here 上的 Google 存储库,Room 不允许对象引用。如何获得 ResultObject
(以及它的外观)包括所有嵌套列表?
ResultObject 应该有这个信息:
List<Dialog>
Dialog
实体有 List<Message>
。
Message
有 List<ImageContent>
.
ImageContent
有 List<ImageContentItem>
对话框
@Entity(tableName = "dialog")
data class Dialog(@PrimaryKey val id String, val title: String)
留言
@Entity(tableName = "message",
foreignKeys = [(ForeignKey(entity = Dialog::class, parentColumns ["id"], childColumns = ["dialogId"]))])
data class Message(@PrimaryKey val id: String, val dialogId: String)
图片内容
@Entity(tableName = "image_content",
foreignKeys = [(ForeignKey(entity = Message::class, parentColumns = ["id"], childColumns = ["messageId"]))])
data class ImageContent(@PrimaryKey val id: String, val messageId: String)
ImageContentItem
@Entity(tableName = "image_content_item",
foreignKeys = [(ForeignKey(entity = ImageContent::class, parentColumns = ["id"], childColumns = ["imageContentId"]))])
data class ImageContentItem(val imageContentId: String,
@PrimaryKey(autoGenerate = true) val id: Long = 1)
道:
@Dao
interface DialogDao {
@Query("SELECT * FROM dialog " +
"INNER JOIN message ON message.dialogId = dialog.id " +
"INNER JOIN image_content ON image_content.messageId = message.id " +
"INNER JOIN image_content_item ON image_content_item.imageContentId = image_content.id")
fun getDialogAllInformation(): Flowable<List<**ResultObject**>>
}
Rooms 与 entity/table 一起使用,它不允许按您的需要管理结构化对象。您唯一可以做的就是单独执行查询,然后构建您的 ResultObject
.
您可以根据需要嵌套 类 定义关系。
class DeepDialog {
@Embedded lateinit var embedded: Dialog
@Relation(parentColumn = "id", entityColumn = "dialogId", entity = Message::class)
lateinit var messages: List<DeepMessage>
}
class DeepMessage {
@Embedded lateinit var embedded: Message
@Relation(parentColumn = "id", entityColumn = "messageId", entity = ImageContent::class)
lateinit var imageContents: List<DeepImageContent>
}
... etc
我认为 Room guys 应该提供更优雅的东西,因为这个解决方案至少有两个问题。
- 它引入了非常烦人的样板文件。
@Relation
注释只能用在列表或集合上,因此它不涵盖您有 1:1 关系的场景。
想象一下,根据定义,您的 Dialog
只有一个 Message
(而不是很多)。在这种情况下,您不希望 DeepDialog
具有 messages: List<>
访问器,而是 message: Message
。我发现的唯一方法是:
class DeepDialog {
@Embedded lateinit var embedded: Dialog
@Relation(parentColumn = "id", entityColumn = "dialogId", entity = Message::class)
internal lateinit var messages: List<DeepMessage>
val message get() = messages.firstOrNull()
}
我有几个实体,您可以在下面看到,问题是当您有多于一层的嵌套时如何正确 select 嵌套列表。如果您查看 github, you can find very simple example, but not something complex. As documentation says here 上的 Google 存储库,Room 不允许对象引用。如何获得 ResultObject
(以及它的外观)包括所有嵌套列表?
ResultObject 应该有这个信息:
List<Dialog>
Dialog
实体有List<Message>
。Message
有List<ImageContent>
.ImageContent
有List<ImageContentItem>
对话框
@Entity(tableName = "dialog")
data class Dialog(@PrimaryKey val id String, val title: String)
留言
@Entity(tableName = "message",
foreignKeys = [(ForeignKey(entity = Dialog::class, parentColumns ["id"], childColumns = ["dialogId"]))])
data class Message(@PrimaryKey val id: String, val dialogId: String)
图片内容
@Entity(tableName = "image_content",
foreignKeys = [(ForeignKey(entity = Message::class, parentColumns = ["id"], childColumns = ["messageId"]))])
data class ImageContent(@PrimaryKey val id: String, val messageId: String)
ImageContentItem
@Entity(tableName = "image_content_item",
foreignKeys = [(ForeignKey(entity = ImageContent::class, parentColumns = ["id"], childColumns = ["imageContentId"]))])
data class ImageContentItem(val imageContentId: String,
@PrimaryKey(autoGenerate = true) val id: Long = 1)
道:
@Dao
interface DialogDao {
@Query("SELECT * FROM dialog " +
"INNER JOIN message ON message.dialogId = dialog.id " +
"INNER JOIN image_content ON image_content.messageId = message.id " +
"INNER JOIN image_content_item ON image_content_item.imageContentId = image_content.id")
fun getDialogAllInformation(): Flowable<List<**ResultObject**>>
}
Rooms 与 entity/table 一起使用,它不允许按您的需要管理结构化对象。您唯一可以做的就是单独执行查询,然后构建您的 ResultObject
.
您可以根据需要嵌套 类 定义关系。
class DeepDialog {
@Embedded lateinit var embedded: Dialog
@Relation(parentColumn = "id", entityColumn = "dialogId", entity = Message::class)
lateinit var messages: List<DeepMessage>
}
class DeepMessage {
@Embedded lateinit var embedded: Message
@Relation(parentColumn = "id", entityColumn = "messageId", entity = ImageContent::class)
lateinit var imageContents: List<DeepImageContent>
}
... etc
我认为 Room guys 应该提供更优雅的东西,因为这个解决方案至少有两个问题。
- 它引入了非常烦人的样板文件。
@Relation
注释只能用在列表或集合上,因此它不涵盖您有 1:1 关系的场景。
想象一下,根据定义,您的 Dialog
只有一个 Message
(而不是很多)。在这种情况下,您不希望 DeepDialog
具有 messages: List<>
访问器,而是 message: Message
。我发现的唯一方法是:
class DeepDialog {
@Embedded lateinit var embedded: Dialog
@Relation(parentColumn = "id", entityColumn = "dialogId", entity = Message::class)
internal lateinit var messages: List<DeepMessage>
val message get() = messages.firstOrNull()
}