Kotlin.如果Room数据库中不存在数据,如何插入新记录

eulz3vhy  于 11个月前  发布在  Kotlin
关注(0)|答案(2)|浏览(109)

我是异步操作的初学者。我的目标是检查是否有特定日期的数据已经存在于房间数据库或没有,如果没有,然后开始从服务器下载并插入到房间。但是我下面的代码在Fragment中执行TODO: Processing Data两次,因为当TODO: download insert new data完成时协程会重新执行它
这里我的代码:
birdDAO.kt

@Query("SELECT * FROM birds_table WHERE birdDate =:rDate ORDER BY birdId")
        fun getBirdBySingleDate(rDate: Int): LiveData<List<Bird>>

字符串

birdRepository.kt

fun getBirdBySingleDate(rDate: Int) = birdDao.getBirdBySingleDate(rDate)

birdViewModel.kt

fun getBirdByDate(rDate: Int) = birdRepository.getBirdBySingleDate(rDate)

片段.kt

private fun loadBirdData(jDate: Int) {
      val listBirdByDate = birdViewModel
            .getBirdByDate(jDate)
            .observe(viewLifecycleOwner){ birds ->
            
                val size = birds.size
                
                if(size > 0) {
                    //TODO Processing Data
                }
                else
                {
                    //TODO: download n insert new data
                
                }
            }
}


问题是如何编写只执行一次Room查询的代码?我尝试删除birdDAO.kt中的LiveData类型,并修改Fragment.kt如下:

private fun loadBirdData(jDate: Int) {
    val listBirdByDate = birdViewModel.getBirdByDate(jDate)

    if(listBirdByDate.isNotEmpty) {
          //TODO Processing Data
    }
    else
    {
          //TODO: download n insert new data
                
    }
}


但是listBirdByDate.isNotEmpty行给了我这个错误:

Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: 
public inline fun <T> Array<out TypeVariable(T)>.isNotEmpty(): Boolean defined in kotlin.collections


或者什么是最好的方式来实现我的目标?谢谢

q5lcpyga

q5lcpyga1#

你可以创建另一个查询来获取特定日期和视图Model中找到的条目的计数,而不是返回鸟类列表,我猜,一旦你验证计数为零,你就想开始从服务器下载数据。
您可以将viewModel从
fun getBirdByDate(rDate:Int)= birdRepository.getBirdBySingleDate(rDate)到

fun getBirdByDate(rDate :Int){
    viewModelScope.launch {
        var count= 2  //we don't want two in db though
        
        //withContext and also with main dispatcher we assure that the count 
        //vairable gets updated , I recently came to know that we can actually  
       // use main as well immediate  on Dispatcher inside viewmodel , so 
        //including it :P 
        //Thanks to #commonware
        withContext(Dispatchers.Main.immediate){
            count = //your repository function to get dao using Dispatche.IO
        }
        if(count == 0){
            //start downloading from server and update data in db
        }else if(count==1){
            //get the list from db
        }else
        {
            //show error
        }
    }
}

字符串
你实际上可以为if和else做更好的逻辑(使用Kotlin的when),我试图给予你一些想法,因为我也是android的新手。

yyhrrdl8

yyhrrdl82#

@Query("SELECT EXISTS(SELECT 1 FROM birds_table)")
  fun hasBirds(): Boolean

字符串
在你的刀上加上上面的代码。然后在逻辑中使用以下代码

if(mDao.hasBirds()) {
                //TODO Processing Data
            } else {
                //TODO: download n insert new data
            }

相关问题