【问题标题】:Room - check if data were fetched recentlyRoom - 检查最近是否获取了数据
【发布时间】:2018-11-27 06:52:53
【问题描述】:

在官方Guide to App Architecture 是存储库的一个例子。检查数据库中是否存在对象以及是否新鲜:

// check if user was fetched recently
boolean userExists = userDao.hasUser(FRESH_TIMEOUT);

任何想法如何为 DAO 实现该功能 (hasUser)?

【问题讨论】:

    标签: android dao android-room android-architecture-components android-jetpack


    【解决方案1】:

    大多数架构组件示例都可以在here 获得。 在您的情况下,我找不到 UserDao 类,但有一个数据库模式示例 hereusers 表有一个 last_update 列。所以你可以这样写 UserDao :

    @Query("SELECT COUNT(*) FROM users WHERE userId == :userId AND last_update >= :timeout)
    int hasUser(int userId, long timeout)
    

    如果ID为userId的用户不够新鲜,则返回0。

    【讨论】:

    • 我明白了,谢谢。但是如何在 DAO 中实现该值的更新呢?我很想为生成的@Insert 类创建Extension
    • 对于插入,您可以像这样定义表格:last_update DATETIME DEFAULT CURRENT_TIMESTAMP。对于更新,我可能会在调用 dao 之前在每个 setter 中更新 User.last_update。 (编辑:已清理。抱歉,猫侵入了我的键盘:D)
    【解决方案2】:

    您应该在表格中添加一个额外的字段,例如带有日期的COLUMN_LAST_FETCHED,并且在每次询问后,使用时间戳更新该字段。

    【讨论】:

      【解决方案3】:

      考虑使用RateLimiter 类,如android-architecture-components GitHub project 中的here 所示,以一种非持久 的方式检查数据是否最近被获取:

      @Singleton 
      @OpenForTesting 
      class RepoRepository @Inject constructor(
          private val appExecutors: AppExecutors,
          private val db: GithubDb,
          private val repoDao: RepoDao,
          private val githubService: GithubService ) {
      
          private val repoListRateLimit = RateLimiter<String>(10, TimeUnit.MINUTES)
      
          fun loadRepos(owner: String): LiveData<Resource<List<Repo>>> {
              return object : NetworkBoundResource<List<Repo>, List<Repo>>(appExecutors) {
                  override fun saveCallResult(item: List<Repo>) {
                      repoDao.insertRepos(item)
                  }
      
                  override fun shouldFetch(data: List<Repo>?): Boolean {
                      return data == null || data.isEmpty() || repoListRateLimit.shouldFetch(owner)
                  }
      
                  override fun loadFromDb() = repoDao.loadRepositories(owner)
      
                  override fun createCall() = githubService.getRepos(owner)
      
                  override fun onFetchFailed() {
                      repoListRateLimit.reset(owner)
                  }
              }.asLiveData()
          }
      
          // Details omitted for brevity.
      }
      

      【讨论】:

      • 但这不会在用户或操作系统杀死应用程序或重新启动设备后继续存在?
      • @Alex 确实这个解决方案不是持久的。有关处理死亡的弹性,请参阅其他答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-12
      • 1970-01-01
      • 2022-12-28
      • 2018-12-10
      • 1970-01-01
      • 2014-03-21
      • 2021-02-12
      相关资源
      最近更新 更多