如何在模型中设置数据?

问题描述

我有一个实体“drinks”,它有 [id;name;thumb] 并且我正在使用这些实体进行 2 次响应调用一个响应返回给我一个 NonAlcohol 饮料列表,另一个AlcoholList,我使用 Room 来缓存数据。但是当我运行应用程序时,我看到我的列表合并了,经过一番思考,我找到了解决这个问题的方法,我在我的实体“alcoholStatus”中添加一个布尔字段。 但是我无法理解如何将数据设置为此变量正确使用此 AccessDataStrategy。我是 Android 新手,这是我的学习项目。请告诉我如何解决这个问题的正确方法

https://github.com/YaroslavSulyma/LetsDrink/tree/master/app/src/main/java/com/example/letsdrink

非常感谢!

实体

@Entity(tableName = "drinks")
data class DrinksModel(
    @Serializedname("strDrink")
    val strDrink: String,@Serializedname("strDrinkThumb")
    val strDrinkThumb: String?,@Serializedname("idDrink")
    @PrimaryKey
    val idDrink: Int,var alcohol: Boolean
)

数据访问策略代码

fun <T,A> performGetoperation(
    databaseQuery: () -> LiveData<T>,networkCall: suspend () -> Resource<A>,saveCallResult: suspend (A) -> Unit
): LiveData<Resource<T>> =
    liveData(dispatchers.IO) {
        emit(Resource.loading())
        val source = databaseQuery.invoke().map { Resource.success(it) }
        emitSource(source)

        val responseStatus = networkCall.invoke()
        if (responseStatus.status == SUCCESS) {
            saveCallResult(responseStatus.data!!)

        } else if (responseStatus.status == ERROR) {
            emit(Resource.error(responseStatus.message!!))
            emitSource(source)
        }
    }

资源

data class Resource<out T>(val status: Status,val data: T?,val message: String?) {

    enum class Status {
        SUCCESS,ERROR,LOADING
    }

    companion object {
        fun <T> success(data: T): Resource<T> {
            return Resource(Status.SUCCESS,data,null)
        }

        fun <T> error(message: String,data: T? = null): Resource<T> {
            return Resource(Status.ERROR,message)
        }

        fun <T> loading(data: T? = null): Resource<T> {
            return Resource(Status.LOADING,null)
        }
    }
}

存储库

class CocktailsRepository @Inject constructor(
        private val remoteDataSource: CocktailsRemoteDataSource,private val localDataSource: CocktailsDao
) {
        fun getAlcoholicCocktails() = performGetoperation(
            databaseQuery = { localDataSource.getAlcoholicCocktails() },networkCall = { remoteDataSource.getAllAlcoholicCocktails()},saveCallResult = { localDataSource.insertAllDrinks(it.drinks) }
        )
    
        fun getNonAlcoholicCocktails() = performGetoperation(
            databaseQuery = { localDataSource.getNonAlcoholicCocktails() },networkCall = { remoteDataSource.getAllNonAlcoholicCocktails() },saveCallResult = { localDataSource.insertAllDrinks(it.drinks) }
        )
    }

DAO

@Dao
interface CocktailsDao {
    @Query("SELECT * FROM drinks WHERE alcohol = 'true'")
    fun getAlcoholicCocktails(): LiveData<List<DrinksModel>>

    @Query("SELECT * FROM drinks WHERE alcohol = 'false'")
    fun getNonAlcoholicCocktails(): LiveData<List<DrinksModel>>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertAllDrinks(drinks: List<DrinksModel>)
}

远程数据源

class CocktailsRemoteDataSource @Inject constructor(private val iCocktailApisService: ICocktailApisService) :
    BaseDataSource() {

    suspend fun getAllAlcoholicCocktails() =
        getResult { iCocktailApisService.allAlcoholicAndNonAlcoholicCocktails("Alcoholic") }

    suspend fun getAllNonAlcoholicCocktails() =
        getResult { iCocktailApisService.allAlcoholicAndNonAlcoholicCocktails("Non_Alcoholic") }
}

解决方法

首先:我强烈建议您为远程和本地模型类定义单独的数据类,并在需要时在它们之间进行映射,例如:

远程数据模型:

data class DrinkRemoteModel(
    @SerializedName("idDrink")
    val idDrink: Int,@SerializedName("strDrink")
    val strDrink: String,@SerializedName("strDrinkThumb")
    val strDrinkThumb: String?,@SerializedName("alcohol")
    var alcohol: Boolean
)

本地数据模型:

@Entity(tableName = "drinks")
data class DrinkLocalModel(
@PrimaryKey
    @ColumnInfo(name = "idDrink")
    val idDrink: Int,@ColumnInfo(name = "strDrink")
    val strDrink: String,@ColumnInfo(name = "strDrinkThumb")
    val strDrinkThumb: String?,@ColumnInfo(name = "alcohol")
    var alcohol: Boolean
)

回到您的实现:我认为导致问题的原因是 Room 将实体中的布尔字段映射到整数列,1 用于 {{ 1}} 和 true 用于 0,因此请尝试更改您在 DAO 中的查询,如下所示:

false

或者:您可以用一个 DAO 函数替换 @Dao interface CocktailsDao { @Query("SELECT * FROM drinks WHERE alcohol = 1") fun getAlcoholicCocktails(): LiveData<List<DrinksModel>> @Query("SELECT * FROM drinks WHERE alcohol = 0") fun getNonAlcoholicCocktails(): LiveData<List<DrinksModel>> @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertAllDrinks(drinks: List<DrinksModel>) } getAlcoholicCocktails,如下所示:

getNonAlcoholicCocktails