Room数据库如何将Section与Category关联映射为SectionWithCategories对象
实现Section关联Category的解决方案
前置准备:配置类型转换器
Room原生不支持直接存储List<String>类型,因此你需要先添加类型转换器,实现List<String>和Json字符串的互转:
import androidx.room.TypeConverter import com.google.gson.Gson import com.google.gson.reflect.TypeToken class Converters { private val gson = Gson() @TypeConverter fun listToString(list: List<String>?): String? { return gson.toJson(list) } @TypeConverter fun stringToList(value: String?): List<String>? { if (value.isNullOrEmpty()) return emptyList() val type = object : TypeToken<List<String>>() {}.type return gson.fromJson(value, type) } }
将转换器添加到你的Room数据库类的注解中:
@Database(entities = [Category::class, Section::class], version = 1) @TypeConverters(Converters::class) abstract class AppDatabase : RoomDatabase() { abstract fun appDao(): AppDao }
实现方案:手动映射(推荐,无需修改现有表结构)
该方案逻辑简单直观,不需要调整现有实体类结构,性能也足够满足常规场景:
- 首先在DAO层定义两个查询方法:
@Dao interface AppDao { // 查询所有Category数据 @Query("SELECT * FROM Category") suspend fun getAllCategories(): List<Category> // 查询所有Section数据 @Query("SELECT * FROM Section") suspend fun getAllSections(): List<Section> }
- 在Repository/ViewModel层完成数据映射:
suspend fun loadSectionWithCategories(): List<SectionWithCategories> { // 先把所有Category转成id为key的Map,后续匹配效率更高 val categoryMap = appDao.getAllCategories().associateBy { it.id } // 遍历每个Section,替换id为对应的Category对象 return appDao.getAllSections().map { section -> SectionWithCategories( name = section.name, // mapNotNull会自动过滤不存在的category_id,避免空指针 categories = section.category_ids.mapNotNull { categoryId -> categoryMap[categoryId] } ) } }
运行上述代码后,返回的List<SectionWithCategories>就是你需要的目标结构。
内容的提问来源于stack exchange,提问作者Dilanka Laksiri
相关产品推荐
相关产品推荐

