如何在Android Room中使用@Relation查询多对一关联数据
问题:Room中多对一关联能否用@Relation注解实现用户关联组的查询?
已知用户与组是多对一关联(一个用户仅归属一个组),实体类定义如下:
@Entity(tableName="user") data class UserEntity( @PrimaryKey(autoGenerate = true) val uid: Int, val username: String, val groupId: Int // 其他字段 ) @Entity(tableName="group") data class GroupEntity( @PrimaryKey(autoGenerate = true) val gid: Int, val name: String, )
我目前通过POJO结合左连接实现了用户关联组的查询,代码如下:
data class UserWithGroup( @Embedded val user: UserEntity, @Embedded val group: GroupEntity, ) @Dao interface UserDao { @Transaction @Query("SELECT * FROM `user` u LEFT JOIN `group` g ON u.group_id = g.id") fun getAllUserWithGroup(): List<UserWithGroup> }
现在想知道:是否可以在UserWithGroup中使用@Relation注解来获取用户关联的组?网上大多示例是查询组及其包含的用户列表,我编写的以下代码能否实现需求?
data class UserWithGroup( @Embedded val user: UserEntity, @Relation( parentColumn = "gid", entityColumn = "groupId", ) val group: GroupEntity ) @Dao interface UserDao { @Transaction @Query("SELECT * FROM `user`") fun getAllUserWithGroup(): List<UserWithGroup> }
回答
可以用@Relation实现多对一的关联查询,但你当前的代码存在参数配置错误,无法正常工作,正确的写法如下:
问题分析
你写的@Relation参数搞反了:
parentColumn应该是父实体(UserEntity)中关联子实体的外键字段,也就是user表的groupIdentityColumn是子实体(GroupEntity)的主键字段,也就是group表的gid
另外,Room的@Relation默认是内连接逻辑,如果需要左连接(即使用户没有组也能查询到),需要额外配置join = Join.LEFT。
正确代码示例
data class UserWithGroup( @Embedded val user: UserEntity, @Relation( parentColumn = "groupId", // UserEntity中的外键字段 entityColumn = "gid", // GroupEntity的主键字段 join = Join.LEFT // 配置左连接,可选,根据需求决定 ) val group: GroupEntity? // 左连接情况下可能为null,建议用可空类型 ) @Dao interface UserDao { @Transaction @Query("SELECT * FROM `user`") fun getAllUserWithGroup(): List<UserWithGroup> }
说明
@Transaction注解必须保留,因为@Relation会触发两次查询:先查所有用户,再批量查询对应的组,事务能保证操作的原子性- 如果你不需要左连接(只查询有对应组的用户),可以去掉
join = Join.LEFT,同时group字段可以设为非空类型 - 这种方式比手动写SQL左连接更符合Room的ORM设计风格,也更易维护
内容的提问来源于stack exchange,提问作者Doe Jam
相关产品推荐
相关产品推荐

