You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于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无法直接解决这个问题,推荐以下高效清理方案:
    1. 事务内批量处理:在同一事务中完成旧数据删除和关联刷新,避免多次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)
          }
      }
      
    2. 利用懒加载自动刷新:ToMany默认是懒加载,调用channel.epgData.reset()后,下次访问该集合时会自动从数据库重新加载有效数据,无需提前遍历所有频道。
    3. 优化查询逻辑:后续使用TvChannel的节目数据时,直接通过epgDataBox按epgChId和日期查询,而非直接访问关联集合,从根源避免无效引用问题。

内容的提问来源于stack exchange,提问作者Alex Mutschl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 23:32:15