关于Objectbox toMany关联的三类技术问题咨询
Objectbox ToMany关联问题解答
现有实体结构
TvChannel实体
@Entity data class TvChannel( @Id var id: Long = 0, var name: String? = "", var epgChId: String? = "" ) { lateinit var epgData: ToMany<EpgData> }
EpgData实体
@Entity data class EpgData( @Id var id: Long = 0, var name: String? = "", var epgChId: String? = "", var epgSourceId: Long? = null, var date: String? = "", var startTimeStamp: Long? = null, var stopTimeStamp: Long? = null )
关联实现代码
for (chann in channels) { val epg = withContext(Dispatchers.IO) { epgDataBox.query(EpgData_.epgChId.equal(chann.epgChId) .and(EpgData_.date.equal(todayDateString))) .build().find() } chann.epgData.addAll(epg) tvChannBox.put(chann) }
问题解答
1. 何时需要在EpgData中添加@Backlink关联?该注解是否必需?
- 这个注解不是必需的,仅在你需要从
EpgData反向查询关联的TvChannel列表时才需要添加。比如你想获取某条EpgData被哪些频道引用,@Backlink(to = "epgData")可以让你直接通过EpgData.tvchannels拿到对应的频道集合。 - 如果业务逻辑只需要从
TvChannel侧查询关联的EpgData,完全不需要添加该注解。
2. 更新EpgData的时间戳后,TvChannel的关联数据会自动同步吗?
会自动同步。ToMany关联基于数据库中的实体引用,TvChannel.epgData指向的是数据库中实际存储的EpgData实例。当你更新EpgData的时间戳并保存到数据库后,下次访问TvChannel.epgData时,Objectbox会自动读取最新的数值。
3. 删除旧EpgData后,TvChannel的关联中是否会保留无效对象?如何高效清理?
- 是的,直接删除
EpgData后,TvChannel.epgData中会残留已删除对象的无效引用(通常表现为对象存在但id为0或数据为空)。 - @Backlink无法直接解决这个问题,推荐以下高效清理方案:
- 事务内批量处理:在同一事务中完成旧数据删除和关联刷新,避免多次IO操作:
boxStore.runInTx { // 1. 删除旧EpgData val oldEpgQuery = epgDataBox.query(EpgData_.date.lessThan(threeDaysAgoString)).build() oldEpgQuery.remove() // 2. 批量刷新关联频道的EpgData // 先查询所有关联过旧EpgData的频道(通过epgChId匹配) val affectedChannels = tvChannBox.query( TvChannel_.epgChId.in(oldEpgIds) // oldEpgIds为已删除EpgData的epgChId集合 ).build().find() for (channel in affectedChannels) { val validEpg = epgDataBox.query( EpgData_.epgChId.equal(channel.epgChId) .and(EpgData_.date.greaterOrEqual(todayMinusThreeDays)) ).build().find() channel.epgData.clear() channel.epgData.addAll(validEpg) tvChannBox.put(channel) } } - 利用懒加载自动刷新:
ToMany默认是懒加载,调用channel.epgData.reset()后,下次访问该集合时会自动从数据库重新加载有效数据,无需提前遍历所有频道。 - 优化查询逻辑:后续使用
TvChannel的节目数据时,直接通过epgDataBox按epgChId和日期查询,而非直接访问关联集合,从根源避免无效引用问题。
- 事务内批量处理:在同一事务中完成旧数据删除和关联刷新,避免多次IO操作:
内容的提问来源于stack exchange,提问作者Alex Mutschl
相关产品推荐
相关产品推荐

