yby*_*byb 4 android kotlin android-room
我制作了一个如图所示的屏幕。
如您所见,它们Set information items
位于red box
.
我想将这些数据存储在Room DB
.
是red box
由 组成Workout Class
,其中包含blue box
( )。WorkoutSetInfo class
我只想从 Room 获取列表set information
。
但是我编写了一个查询来获取 的列表set information
,但出现以下错误:
error: The columns returned by the query does not have the fields [id,set,weight,reps] in com.example.lightweight.data.db.entity.WorkoutSetInfo even though they are annotated as non-null or primitive. Columns returned by the query: [sets]
public abstract androidx.lifecycle.LiveData<java.util.List<com.example.lightweight.data.db.entity.WorkoutSetInfo>> getWorkoutSetInfoList()
Run Code Online (Sandbox Code Playgroud)
我的类似问题已经有好几个了,但我还是没能解决。如何只获取设置信息的列表?
锻炼设置信息
data class WorkoutSetInfo(
val id: String = UUID.randomUUID().toString(), // For comparison in DiffUtil.
val set: Int,
val weight: String = "",
val reps: String = ""
)
Run Code Online (Sandbox Code Playgroud)
锻炼
@Entity
data class Workout(
@PrimaryKey(autoGenerate = true)
val id: Int,
val title: String = "",
val unit: String = "kg",
val memo: String = "",
var sets: List<WorkoutSetInfo> = emptyList()
)
Run Code Online (Sandbox Code Playgroud)
DAO
@Dao
interface WorkoutDao {
@Query("SELECT sets FROM Workout")
fun getWorkoutSetInfoList() : LiveData<List<WorkoutSetInfo>>
@Insert
fun insert(workout: Workout)
}
Run Code Online (Sandbox Code Playgroud)
存储库
class WorkoutRepository(private val workoutDao : WorkoutDao, title: String) {
val workout = Workout(0, title)
var setInfoList : ArrayList<WorkoutSetInfo> = arrayListOf()
val _items: LiveData<List<WorkoutSetInfo>> = workoutDao.getWorkoutSetInfoList()
fun add(item: WorkoutSetInfo) {
setInfoList.add(item)
workout.sets = setInfoList
workoutDao.insert(workout)
}
}
Run Code Online (Sandbox Code Playgroud)
视图模型
class DetailViewModel(application: Application, title: String) : ViewModel() {
private val repository: WorkoutRepository
private lateinit var _items: LiveData<List<WorkoutSetInfo>>
val items = _items
private val list: List<WorkoutSetInfo>
get() = _items.value ?: emptyList()
init {
val workoutDao = DetailDatabase.getDatabase(application)!!.workoutDao()
repository = WorkoutRepository(workoutDao, title)
_items = repository._items
}
fun addDetail() {
viewModelScope.launch(Dispatchers.IO){
val item = WorkoutSetInfo(set = list.size+1)
repository.add(item)
}
}
}
Run Code Online (Sandbox Code Playgroud)
更新
class Converter {
@TypeConverter
fun listToJson(value: List<WorkoutSetInfo>) : String {
return Gson().toJson(value)
}
@TypeConverter
fun jsonToList(value: String) : List<WorkoutSetInfo> {
return Gson().fromJson(value, Array<WorkoutSetInfo>::class.java).toList()
}
}
Run Code Online (Sandbox Code Playgroud)
您正在尝试将复杂对象的列表保存在列中。Room不知道如何保存它。
var sets: List<WorkoutSetInfo> = emptyList()
<-- 这很复杂
请记住,room 下面只是 sqlite,您的实体代表表。Sqlite 可以识别基本类型,但默认情况下它无法存储复杂对象的列表。如果您想将此对象保存在同一个表中,您可以探索TypeConverters作为解决方案。
请参阅下面的使用单独表的关系解决方案:
您在这里寻找的是一对多关系。单个Workout
可以有一个或多个WorkoutSetInfo
在关系数据库的世界中,您可以通过使用单独的表来表示这一点,并使用工作的WorkoutSetInfo
id来创建关系。id
@Entity
data class WorkoutSetInfo(
val id: String = UUID.randomUUID().toString(), // For comparison in DiffUtil.
val set: Int,
val weight: String = "",
val reps: String = "",
val workoutId: String // <-- this is the id of the workout that this set is associated with
)
Run Code Online (Sandbox Code Playgroud)
完成后,您可以编写联接查询或使用数据对象进行查询,如此处定义的
你可以有这样的东西:
data class WorkoutWithSets(
@Embedded val workout: Workout,
@Relation(
parentColumn = "id",
entityColumn = "workoutId"
)
val sets: List<WorkoutSetInfo>
)
Run Code Online (Sandbox Code Playgroud)
并使用类似的东西来查询它
@Transaction
@Query("SELECT * FROM Workout WHERE id = :workoutId")
fun getWorkoutWithSets(workoutId: String) : LiveData<WorkoutWithSets>
Run Code Online (Sandbox Code Playgroud)
这将给出给定 ID 的锻炼以及与集合表中该锻炼 ID 匹配的所有集合。
归档时间: |
|
查看次数: |
5402 次 |
最近记录: |