如何向Room数据库添加List<String>与List<Object>类型的列?
解决Room数据库添加List类型列的问题
SQLite本身没有原生的List类型,直接在ALTER TABLE里用List<Car>或List<String>是不合法的。Room需要通过**类型转换器(TypeConverter)**将集合类型转换为数据库支持的TEXT类型(存储为JSON字符串)来实现,步骤如下:
1. 修改ALTER TABLE语句
将列类型改为SQLite支持的TEXT,因为我们要把集合序列化为JSON字符串存储:
execSQL("ALTER TABLE table ADD COLUMN cars TEXT") execSQL("ALTER TABLE table ADD COLUMN fuel TEXT")
2. 创建类型转换器
编写转换器类,负责List与String(JSON格式)之间的双向转换。下面以Gson为例(也可以用Kotlinx Serialization、Moshi等序列化库):
class Converters { private val gson = Gson() // List<String> ↔ String @TypeConverter fun stringListToJson(list: List<String>?): String? = gson.toJson(list) @TypeConverter fun jsonToStringList(json: String?): List<String>? { return json?.let { val type = object : TypeToken<List<String>>() {}.type gson.fromJson(it, type) } ?: emptyList() } // List<Car> ↔ String @TypeConverter fun carListToJson(list: List<Car>?): String? = gson.toJson(list) @TypeConverter fun jsonToCarList(json: String?): List<Car>? { return json?.let { val type = object : TypeToken<List<Car>>() {}.type gson.fromJson(it, type) } ?: emptyList() } }
3. 注册类型转换器
在你的Room数据库类上添加@TypeConverters注解,将转换器全局注册:
@Database(entities = [YourEntity::class], version = 2) // 必须升级数据库版本 @TypeConverters(Converters::class) abstract class AppDatabase : RoomDatabase() { // 定义DAO接口 abstract fun yourDao(): YourDao }
4. 更新实体类
在对应的实体类中添加List类型的字段,默认值设为listOf():
@Entity(tableName = "table") data class YourEntity( // 原有字段... val cars: List<Car> = listOf(), val fuel: List<String> = listOf() )
注意事项
- 数据库版本号必须递增,否则Room会检测到结构变化抛出异常。
- 如果使用Kotlinx Serialization替代Gson,只需替换转换器中的序列化逻辑,确保
Car类添加@Serializable注解。 - 确保
Car类有默认构造函数(Gson需要),或对应序列化库要求的结构。
内容的提问来源于stack exchange,提问作者Mark Delphi
相关产品推荐
相关产品推荐

