Kotlin中如何实现Network Service模型与Room Entities双向转换
实现方案
前置修正
你当前的DatabaseRoot里的@Embedded注解使用有误,@Embedded仅支持嵌套普通数据类,无法作用于列表类型。你已经实现了对应列表的TypeConverter,直接删除@Embedded注解即可,Room会自动调用转换器将List<DatabaseResults>序列化为JSON字符串存入数据库。
另外记得在你的Room Database类上添加转换器注册注解,确保转换器生效:
@Database(entities = [DatabaseRoot::class], version = 1) @TypeConverters(DatabaseResultsTypeConverter::class) // 新增这行 abstract class AppDatabase : RoomDatabase() { // ... DAO定义 }
双向转换代码实现
嵌套列表的转换逻辑很简单,在外层对象转换时,对内层列表的每一项单独做类型映射即可,具体实现如下:
网络模型转Room实体
fun List<Root>.asDatabaseModel(): Array<DatabaseRoot> { return map { networkRoot -> DatabaseRoot( page = networkRoot.page, // 对results列表每一项做类型转换 results = networkRoot.results.map { networkResult -> DatabaseResults( adult = networkResult.adult, backdrop_path = networkResult.backdrop_path, genre_ids = networkResult.genre_ids, id = networkResult.id, original_language = networkResult.original_language, original_title = networkResult.original_title, overview = networkResult.overview, popularity = networkResult.popularity, poster_path = networkResult.poster_path, release_date = networkResult.release_date, title = networkResult.title, video = networkResult.video, vote_average = networkResult.vote_average, vote_count = networkResult.vote_count ) }, total_pages = networkRoot.total_pages, total_results = networkRoot.total_results ) }.toTypedArray() }
Room实体转网络域模型
fun List<DatabaseRoot>.asDomainModel(): List<Root> { return map { dbRoot -> Root( page = dbRoot.page, // 反向转换列表每一项 results = dbRoot.results.map { dbResult -> Results( adult = dbResult.adult, backdrop_path = dbResult.backdrop_path, genre_ids = dbResult.genre_ids, id = dbResult.id, original_language = dbResult.original_language, original_title = dbResult.original_title, overview = dbResult.overview, popularity = dbResult.popularity, poster_path = dbResult.poster_path, release_date = dbResult.release_date, title = dbResult.title, video = dbResult.video, vote_average = dbResult.vote_average, vote_count = dbResult.vote_count ) }, total_pages = dbRoot.total_pages, total_results = dbRoot.total_results ) } }
可选优化
如果不想手动逐个映射字段,可以引入MapStruct框架自动生成转换代码,减少模板代码量,同时避免手写字段映射出错的问题。
内容的提问来源于stack exchange,提问作者Víctor Martín
相关产品推荐
相关产品推荐

