我正在使用Room实现本地缓存。我创建了类型转换器来将对象列表转换为 json 并返回。但是我在从 json 检索数据时收到映射问题并出现错误:
The columns returned by the query does not have the fields [title,media] in
com.example.theApp.data.FlickrImage even though they are annotated as non-null or
primitive. Columns returned by the query: [items]
另一个像这样:
error: Cannot figure out how to read this field from a cursor.
private final com.example.theApp.data.Media media = null;
我在这里尝试了其他答案,但它与此问题没有直接关系。
这是我的变型器:
class FlickrImageConverters {
@TypeConverter
fun fromImageListToJson(stat: List<FlickrImage>): String {
return Gson().toJson(stat)
}
/**
* Convert a json to a list of Images
*/
@TypeConverter
fun fromJsonToImagesList(jsonImages: String): List<FlickrImage> {
val type = object : TypeToken<List<FlickrImage>>() {}.type
return Gson().fromJson<List<FlickrImage>>(jsonImages, type)
}
}
这是我的实体类:
@Entity
data class DatabaseImagesEntity(
@PrimaryKey
@TypeConverters(FlickrImageConverters::class)
@SerializedName("item")
val items: List<FlickrImage>)
道类@Dao 接口图像道{
@Query("select * from DatabaseImagesEntity")
fun getImages(): List<FlickrImage>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(images: List<FlickrImage>)
}
FlickrImage 类
data class FlickrImage(val title: String, val media: Media)
媒体类
data class Media(val m: String)
最新图像类
data class LatestImages(val items: List<FlickrImage>)
如果您遇到此问题以及是否知道解决方案,请告诉我。
房间数据库实现
@Database(entities = [DatabaseImagesEntity::class], version = 1,
exportSchema = false)
@TypeConverters(FlickrImageConverters::class)
abstract class FlickrDatabase: RoomDatabase() {
abstract val imagesDao: ImagesDao
}
private lateinit var INSTANCE: FlickrDatabase
fun getDatabase(context: Context): FlickrDatabase{
synchronized(FlickrDatabase::class.java){
if(!::INSTANCE.isInitialized){
INSTANCE = Room.databaseBuilder(context.applicationContext,
FlickrDatabase::class.java,
"flickerImages").build()
}
}
return INSTANCE
}
问题是我将数据保存在错误的实体,错误的类型转换器中,因此,我在创建数据库时使用错误的实体类。
以下是我为存储对象列表而必须进行的必要更改:
Flickr data class
@Entity(tableName = "FlickerImage")
data class FlickrImage(
@PrimaryKey(autoGenerate = true)
val id: Int,
val title: String,
@TypeConverters(MediaConverter::class)
val media: Media)
类型转换器媒体类
class MediaConverter {
@TypeConverter
fun fromMediaToJson(stat: Media): String {
return Gson().toJson(stat)
}
/**
* Convert a json to a list of Images
*/
@TypeConverter
fun fromJsonToMedia(jsonImages: String): Media {
val type = object : TypeToken<Media>() {}.type
return Gson().fromJson<Media>(jsonImages, type)
}
}
道类
@Dao
interface ImagesDao {
@Query("select * from FlickerImage")
fun getImages(): LiveData<List<FlickrImage>>
数据库类
@Database(entities = [FlickrImage::class], version = 1, exportSchema = false)
@TypeConverters(MediaConverter::class)
abstract class FlickrDatabase: RoomDatabase() {
abstract val imagesDao: ImagesDao
}
private lateinit var INSTANCE: FlickrDatabase
fun getDatabase(context: Context): FlickrDatabase{
synchronized(FlickrDatabase::class.java){
if(!::INSTANCE.isInitialized){
INSTANCE = Room.databaseBuilder(context,
FlickrDatabase::class.java,
"flickerImages").build()
}
}
return INSTANCE
}
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAll(images: List<FlickrImage>)
}
您需要向数据类添加适当的注释 - 例如,对于 Gson,您需要添加注释@SerializedName("field_name")
否则,转换器无法知道如何翻译 json。
澄清一下,您当前的批注仅适用于 Room。只需检查您使用的任何 json 库以获取必要的逻辑。
@Entity(tableName = "images")
data class DatabaseImagesEntity(
@PrimaryKey(autoGenerate = true)
var id: Int? = 0,
@TypeConverters(FlickrImageConverters::class)
@SerializedName("item")
val items: MutableList<FlickrImage>? = null
)
或
@Entity(tableName = "images")
class DatabaseImagesEntity {
@PrimaryKey(autoGenerate = true)
var id: Int? = 0
@TypeConverters(FlickrImageConverters::class)
@SerializedName("item")
val items: MutableList<FlickrImage>? = null
}
然后将您的 DAO 查询更新为@Query("select * from images")
我将其命名为图像作为示例 - 您可以选择任何您想要的东西。
class ListConverter {
//从列表到字符串
@TypeConverter
fun fromList(list : List<Object>): String {
return Gson().toJson(list)
}
从字符串到列表
@TypeConverter
fun toList(data : String) : List<Object> {
if (data == null){
return Collections.emptyList()
}
val typeToken = object : TypeToken<List<Object>>() {}.type
return Gson().fromJson(data,typeToken)
}
}