前言
Room是Google 新推出的Jetpack组件库中一款操作数据库的SQLITE ORM库。其风格类似Retrofit,使用注解+接口声明形式,简化了数据库的操作。
随着时间的推迟,Room迭代更新的版本也越来越快,到目前(本文所写时间为止)最新的版本是2.1.0-alpha02,它的一些API也做了调整,本文是记录一次@TypeConverters(ThumbConverter::class)的使用
本文是以Kotlin语言实例,Java语法类似
定义实体类 News.kt
@Entity
data class News(
@PrimaryKey
var row: String,
var title: String = "",
var type: Int = 2,
val thumb: List<String>?,
var content_time: String? = "",
var source: String? = "",
var hot: Int = 0
)
发现Android Studio会报如下错误,编译不通过,原因是@Entity定义的thumb字段无法识别List<String>?类型(非基础类型),最终映射成数据库字段,所以Room提供一个解决方案:手动做类型转换,用转换类告诉Room该如何转换成数据库支持的类型。
/Users/Documents/code/news_android2.0/module_news/build/tmp/kapt3/stubs/debug/com/zm/module/news/repository/entity/News.java:15: 错误: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
private final java.util.List<java.lang.String> thumb = null;
^
定义TypeConverter类
class ThumbConverter {
@TypeConverter
fun getThumbFromString(value: String):List<String>? {
return value.split(",")
}
@TypeConverter
fun storeThumbToString(list: List<String>): String {
val str = StringBuilder(list[0])
list.forEach {
str.append(",").append(it)
}
return str.toString()
}
}
@TypeConverter的两个方法是成对出现的,方法名称可以任意命名,重点在入参和出参类型,必须是需要转换的类型和最终转换后的类型,这点想一下原理能明白了。上面示例写入时将List<String>类型转换成以“,”逗号拼接的String类型,读取时再将逗号分割的字符串转换成List<String>类型。
Room 2.0@TypeConverters调整
经过上面的定义依然是无法编译通过的,原因是Entity类还需要添加这里@TypeConverters,强调一下@TypeConverters 是有s的
,要与转换类方法上的@TypeConverter做区别。在现有的很多文章里提到@TypeConverters都是加到属性上的
,如:stackoverflow上的问答,在Room 2.0是会报错的,因为现在已经改为加到Entity类
上面了。
错误的
@TypeConverters(ThumbConverter::class)
val thumb: List<String>?,
正确的
@Entity
@TypeConverters(ThumbConverter::class)
data class News(
@PrimaryKey
var row: String,
var title: String = "",
var type: Int = 2,
val thumb: List<String>?,
var content_time: String? = "",
var source: String? = "",
var hot: Int = 0
)
后记
多个转换类可以@TypeConverters(ThumbConverter::class,XXXX::Converter::class)
定义。
网友评论