Room 如何类型转换一个非常复杂的数据类?

问题描述 投票:0回答:1

我想使用 Room 数据库来存储关于我的 Itineraries 的数据,但问题是我的 Itinerary 数据类非常复杂,因为来自 API 调用的数据量很大。为这些类型的类编写类型转换器的最佳方式是什么?

主类存放在Room

data class ItineraryModel(
    @PrimaryKey(autoGenerate = true)
    val itineraryId: Int = 0,

    @ColumnInfo(name = "price_details")
    @TypeConverters(PriceDetailsModelConverter::class)
    val priceDetails: PriceDetailsModel? = null,

    @ColumnInfo(name = "slice_data")
    @TypeConverters(SliceDataModelConverter::class)
    val sliceData: SliceDataModel? = null
)

SliceDataModel

data class SliceDataModel(
    val slice: SliceModel
)

切片模型

data class SliceModel(
    val info: InfoSliceModel,
    val airline: AirlineModel,
    val arrival: ArrivalModel,
    val departure: DepartureModel,
    val flightData: FlightDataModel
)

InfoSliceModel

data class InfoSliceModel(
    val connectionCount: Int,
    val duration: String,
    val id: Int,
    val stopCount: Int
)

航空公司模型

data class AirlineModel(
    val logo: String,
    val name: String
)

到达/离开模型(相同)

data class ArrivalModel(
    val airport: AirportModel,
    val datetime: DatetimeModel
)

机场模型

data class AirportModel(
    val city: String,
    val code: String,
    val country: String,
    val name: String,
)

日期时间模型

data class DatetimeModel(
    val date: String,
    val dateDisplay: String,
    val time24h: String,
)

飞行数据模型

data class FlightDataModel(
    val flights: List<FlightModel>
)

飞行模型

data class FlightModel(
    val arrival: ArrivalModel,
    val departure: DepartureModel,
    val info: InfoModel
)

信息模型

data class InfoModel(
    val aircraft: String,
    val aircraftType: String,
    val cabinClass: String,
    val cabinName: String,
    val duration: String,
    val stopCount: Int
)

如您所见,有很多数据。我怎样才能最佳地转换它?

android kotlin retrofit android-room
1个回答
1
投票

一个简单的解决方案是使用序列化库,它允许将大而复杂的对象转换为

String
JSON,因此您可以轻松地将它们存储在 Room 数据库中。我推荐使用 Kotlinx.serialization 库,你可以按照这个 link 使用 Gradle 进行设置。

安装库后,用

@Serializable
注释所有数据类。例如:

@Serializable
@Entity
data class ItineraryModel(
    @PrimaryKey(autoGenerate = true)
    val itineraryId: Int = 0,

    @ColumnInfo(name = "price_details")
    @TypeConverters(PriceDetailsModelConverter::class)
    val priceDetails: PriceDetailsModel? = null,

    @ColumnInfo(name = "slice_data")
    @TypeConverters(SliceDataModelConverter::class)
    val sliceData: SliceDataModel? = null
)

对模型中涉及的所有其他数据类执行相同的操作。完成此操作后,转到您的类型转换器:

价格详情型号转换器:

class PriceDetailsModelConverter {

    @TypeConverter
    fun convertToJsonString(priceDetails: PriceDetailsModel?): String {
         return Json.encodeToString(priceDetails)
    }

    @TypeConverter
    fun convertToObject(json: String): PriceDetailsModel? {
         return Json.decodeFromString(json)
    }

}

SliceDataModelConverter:

class SliceDataModelConverter {

    @TypeConverter
    fun convertToJsonString(sliceDetails: SliceDataModel?): String {
         return Json.encodeToString(sliceDetails)
    }

    @TypeConverter
    fun convertToObject(json: String): SliceDataModel? {
         return Json.decodeFromString(json)
    }

}

一切正常,当存储大模型对象时,

priceDetails
sliceDetails
将以字符串 JSON 的形式存储,当您查询数据库时,您将收到它们作为模型对象。

稍后,如果您想根据价格条件选择行,则必须使用

LIKE
sql 运算符,因为
priceDetails
存储为字符串,这可能是这种方法的唯一缺点。

© www.soinside.com 2019 - 2024. All rights reserved.