Android Room如何将子查询结果映射到实体非列参数
解决Room查询中映射关联表记录数到实体类字段的问题
没问题,我来帮你搞定这个Room查询的映射问题。要实现把RecordingAndTags里的关联记录数映射到Tag的totalRecords字段,需要两步调整:
1. 修改Tag实体类,允许Room映射totalRecords字段
原来的totalRecords字段加了@Ignore注解,Room会忽略这个字段,所以必须先移除这个注解,这样Room才能把查询结果映射到这个字段上。同时别忘了添加上对应的getter和setter方法(Room需要这些来访问字段):
@Entity public class Tag { @PrimaryKey(autoGenerate = true) private long id; @ColumnInfo(name = "name") private String name; // 移除@Ignore注解,让Room可以映射查询结果到该字段 private int totalRecords; // 对应的getter和setter方法 public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getTotalRecords() { return totalRecords; } public void setTotalRecords(int totalRecords) { this.totalRecords = totalRecords; } }
2. 更新DAO中的查询语句,关联计算记录数
接下来修改DAO里的查询方法,用子查询计算每个Tag对应的RecordingAndTags记录数,并且把结果别名设为totalRecords(要和实体类的字段名完全一致,Room才能正确映射):
@Query("SELECT t.id, t.name, " + "(SELECT COUNT(id) FROM RecordingAndTags WHERE tagId = t.id) AS totalRecords " + "FROM Tags t " + "ORDER BY importance DESC, name ASC") LiveData<List<Tag>> getAllWithRecordCounts();
几个关键细节说明:
- 我没有用
SELECT *,而是明确指定了要查询的字段(t.id、t.name),这样能避免如果Tags表新增字段时可能出现的映射问题,更稳妥。 - 子查询
(SELECT COUNT(id) FROM RecordingAndTags WHERE tagId = t.id)会针对每个Tag,统计关联的RecordingAndTags记录数,别名totalRecords必须和实体类的字段名匹配。 - 保留了你原来的排序规则
ORDER BY importance DESC, name ASC,如果你的Tags表没有importance字段,记得根据实际情况调整这条语句,避免语法错误。
这样调整后,调用getAllWithRecordCounts()方法就能拿到包含每个标签对应记录数的Tag列表了。
内容的提问来源于stack exchange,提问作者nLL
相关产品推荐
相关产品推荐

