Android房间多对多连接表获得超过2个表的关系 [英] Android Room Many to Many Junction table getting more than relation of 2 tables

查看:37
本文介绍了Android房间多对多连接表获得超过2个表的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了User、Property和这两个项目UserPropertyJunction的连接表之间的关系,可以在下图中可视化为关系

UserEntity,而不是customers,后者为

@Entity(tableName = "user")
data class UserEntity(
    @PrimaryKey
    val userId: Long,
    val firstName: String,
    val lastName: String,
    val email: String,
    val password: String
)

属性,而不是products

@Entity(
    tableName = "property",
    primaryKeys = ["id"]
)
data class Property(
    val id: Int,
    val update: Int,
    val categoryId: Int,
    val title: String,
    val subject: String,
    val type: String,
    val typeId: Int
}

AND连接表代替PRODUCT_HELPER

@Entity(
    tableName = "user_property_junction",
    primaryKeys = ["userAccountId", "propertyId"],
    // Foreign Keys
    foreignKeys = [
        ForeignKey(
            entity = User::class,
            parentColumns = ["userId"],
            childColumns = ["userAccountId"],
            onDelete = ForeignKey.NO_ACTION
        ),
        ForeignKey(
            entity = Property::class,
            parentColumns = ["id"],
            childColumns = ["propertyId"],
            onDelete = ForeignKey.NO_ACTION
        )
    ]
)
data class UserPropertyJunction(
    val userAccountId: Long,
    val propertyId: Int
)

并使用

创建了关系类
data class UserWithFavorites(

    @Embedded
    val user: User,

    @Relation(
        parentColumn = "userId",
        entity = Property::class,
        entityColumn = "id",
        associateBy = Junction(
            value = UserPropertyJunction::class,
            parentColumn = "userAccountId",
            entityColumn = "propertyId"
        )
    )
    val propertyList: List<Property>
)

还需要获取这些属性被用户显示和点赞的次数的数据。

以及签出的解决方案in this link,该解决方案向交汇点添加附加字段,在我的示例中添加了displayCountfavorite属性

data class UserPropertyJunction(
    val userAccountId: Long,
    val propertyId: Int,
    val displayCount:Int=0,
    val favorite:Boolean=false
)

我的第一个问题是,据我所见,我对连接表或关联表没有太多经验,它们只存储应该关联的表的外键,可以在连接表中添加值字段吗?

如果不是很优雅或不是首选的方式,我是否应该添加另一个与连接表有关系的表,如

data class PropertyStatus(
    val userAccountId: Long,
    val propertyId: Int,
    val displayCount:Int=0,
    val favorite:Boolean=false
)

并将其关联?

同时从用户属性和属性状态检索数据时,是否应手动从

获取数据
data class UserWithProperties(

    @Embedded
    val user: User,

    @Relation(
        parentColumn = "userId",
        entity = Property::class,
        entityColumn = "id",
        associateBy = Junction(
            value = UserPropertyJunction::class,
            parentColumn = "userAccountId",
            entityColumn = "propertyId"
        )
    )
    val propertyList: List<Property>
)
根据您对第一个问题的回答,使用SELECT FROM STATUS表或连接表进行GET 或者是否可以使用@Embedded@Relation

UserWithProperties添加另一个关系

推荐答案

据我所知,不幸的是,没有开箱即用的方法,即如何仅使用聊天室的工具(@Relation、@Embedded、@Junction)解决您的用例。

我的第一个问题是,据我所见,我对连接表或关联表没有太多经验,它们只存储应该关联的表的外键,可以在连接表中添加值字段吗?

问题是@Junction在使用上有一些限制-它只有助于将两个表与保存在第三个(连接)表中的值绑定。但是@Relation-with-@Junction API不支持从该连接表获取任何要包含到结果类的字段(这些外键仅用于绑定)。这就是为什么从技术上讲,您可以将一些字段添加到连接表中(它似乎是您应该保存这些值的最合适位置),但实际上您无法使用@Junction获取这些字段。

也许有一些黑客方法可以用来实现这一点,但我猜-您必须使用SQL连接实现您自己的方法,并使用循环传递结果以形成所需的结果(类似于您在帖子中提到的链接中实现的方法)。

作为您的简化,您可以真正按照您的建议描述实体连接表(但根本不使用@Junction):

data class UserPropertyJunction(
    val userAccountId: Long,
    val propertyId: Int,
    val displayCount:Int=0,
    val favorite:Boolean=false
)

然后添加辅助类(非实体)作为查询结果:

data class UserWithFavorites(
    val displayCount:Int,
    val favorite:Boolean,
    @Relation(
         parentColumn = "userAccountId",
         entityColumn = "userId"
    )
    val user: UserEntity,
    @Relation(
         parentColumn = "propertyId",
         entityColumn = "id"
    )
    val property: Property,
)

当然,这不是您想要的,但至少您可以处理它,它是开箱即用的,您可以对其使用LiveData/Flow/RxJava(例如,在获得它之后,您可以尝试使用一些转换操作符以某种方式将其更改为所需的格式)

更新(简化版)

如果您的结果中不需要用户,但是您只想通过userID来过滤,那么您的辅助类可以如下所示:

data class PropertiesWithFavorites(
    val displayCount:Int,
    val favourite:Boolean,
    val propertyId: Long,
    @Relation(
         parentColumn = "propertyId",
         entityColumn = "id"
    )
    val property: Property
)

和道法:

@Query("SELECT * FROM user_property_junction as j where j.userAccountId =:userId")
fun getPropertiesByUser(userId: Long): List<PropertiesWithFavorites>  

这篇关于Android房间多对多连接表获得超过2个表的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆