成功设计房间数据库模式后,如何获取属于网络响应中另一条记录的记录列表

How to get the list of record that is a part of another record in the network response, after successully designing the room database schema

我想要达到的目标

我正在开发一个天气预报应用程序,它有空间作为本地缓存数据库,用于 json 我从 openweathermap api 获得的响应如下

{
   "cod":"200",
   "message":0,
   "cnt":40,
   "list":[
      {
         "dt":1590602400,
         "main":{
            "temp":306.2,
            "feels_like":306.4,
            "temp_min":306.07,
            "temp_max":306.2,
            "pressure":1006,
            "sea_level":1004,
            "grnd_level":950,
            "humidity":41,
            "temp_kf":0.13
         },
         "weather":[
            {
               "id":802,
               "main":"Clouds",
               "description":"scattered clouds",
               "icon":"03n"
            }
         ],
         "clouds":{
            "all":48
         },
         "wind":{
            "speed":3.72,
            "deg":183
         },
         "sys":{
            "pod":"n"
         },
         "dt_txt":"2020-05-27 18:00:00"
      },
      {
         "dt":1590613200,
         "main":{
            "temp":305.05,
            "feels_like":303.65,
            "temp_min":304.7,
            "temp_max":305.05,
            "pressure":1004,
            "sea_level":1003,
            "grnd_level":949,
            "humidity":38,
            "temp_kf":0.35
         },
         "weather":[
            {
               "id":803,
               "main":"Clouds",
               "description":"broken clouds",
               "icon":"04n"
            }
         ],
         "clouds":{
            "all":68
         },
         "wind":{
            "speed":4.72,
            "deg":197
         },
         "sys":{
            "pod":"n"
         },
         "dt_txt":"2020-05-27 21:00:00"
      },
      {
         "dt":1590624000,
         "main":{
            "temp":302.97,
            "feels_like":304.29,
            "temp_min":302.74,
            "temp_max":302.97,
            "pressure":1004,
            "sea_level":1004,
            "grnd_level":949,
            "humidity":46,
            "temp_kf":0.23
         },
         "weather":[
            {
               "id":802,
               "main":"Clouds",
               "description":"scattered clouds",
               "icon":"03n"
            }
         ],
         "clouds":{
            "all":47
         },
         "wind":{
            "speed":1.48,
            "deg":196
         },
         "sys":{
            "pod":"n"
         },
         "dt_txt":"2020-05-28 00:00:00"
      }
   ],
   "city":{
      "id":1269843,
      "name":"Hyderabad",
      "coord":{
         "lat":17.3753,
         "lon":78.4744
      },
      "country":"IN",
      "population":3597816,
      "timezone":19800,
      "sunrise":1590538296,
      "sunset":1590585318
   }
} 

根据 json 响应,我有以下房间架构的数据 classes

Record.class

@Entity(tableName = "Record")
data class Record(
    @PrimaryKey(autoGenerate = true)
    val rid:Long,
    @SerializedName("dt_txt")
    val dtTxt: String,
    @Embedded(prefix = "main_")
    val main: Main,
    @Embedded(prefix = "rain_")
    val rain: Rain,
    @Embedded(prefix = "wind_")
    val wind: Wind
)

Weather.class

@Entity(
    tableName = "weather",
    foreignKeys = [
    ForeignKey(
        entity = Record::class,
        parentColumns = ["rid"],
        childColumns = ["wid"],
        onDelete = CASCADE
    )
])
data class Weather(
    @PrimaryKey(autoGenerate = true)
    val wid:Long,
    val description: String,
    val icon: String,
    val id: Int,
    val main: String
)

天气Record.class

class WeatherRecord (
    @Embedded
    val record: Record,
    @Relation(parentColumn = "rid", entityColumn = "wid")
    val weather:List<Weather>
)

还有其他 class 元素,例如 Rain、Main、Wind、City 等

现在我得到的响应 class 是

WeatherResponse.class

data class WeatherResponse(
    val city: City,
    val cnt: Int,
    val cod: String,
    val list: List<Record>,
    val message: Int
)

到目前为止我做了什么

根据 JSON 的响应,可以很容易地理解天气应该是记录中的一个字段 class 但它不存在,这是因为天气以列表的形式出现,因为其中,我在 Dao 查询中使用了外键和一些小技巧(如以下答案( 中所述),以便存储列表并在数据库中获取天气列表

道Class

@Dao
interface WetherDataDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun upsert(data: Record)
    @Insert
    fun insert(weather:List<Weather>)
    @Transaction
    fun insert(weatherRecord: WeatherRecord){
        upsert(weatherRecord.record)
        insert(weatherRecord.weather)
    }

    @Query("Select * from Record")
    fun getAllRecords():LiveData<WeatherRecord>
}

我有什么问题

因此,在实施房间之前,我得到了正确的响应(即天气作为记录的一部分),但之后我没有将天气作为记录的一部分,也没有其他地方。 我试图通过将 WeatherRecord class 中的列表类型从 Record 更改为 WeatherRecord 来解决问题,但这也没有解决我的问题(它只是用一些代码打印 class 的路径请参阅屏幕截图 ) 所以任何人都可以帮助我解决这个问题你可以建议我任何其他可能改变整个数据库设计模式的可能解决方案,我将很乐意学习

由于我是新手,所以您可以向我推荐一些有趣的博客,介绍我如何为这种复杂的数据库设计数据库模式

提前致谢

不知道我的回答是否有帮助。更多的是原则,而不是实际指导

一些思考

应用中有几种类型的数据classes'组:

  • "Transfer"组。该组的结构由传输接口组成。例如,您有 Android 应用程序,并且有后端。你有一些 JSON-协议,你决定使用 Retrofit,所以要以正确的形式获取数据,你必须根据 JSON 结构构建你的 classes。

  • "Database"组。这个组的结构不是那么严格,但是如果你使用关系数据库(SQLite 是其中之一),你必须遵循一些要求。例如,您不能将另一个对象用作 table 的字段(只是外键)等等。

  • "Business logic"组。该组的结构几乎没有限制,必须在应用程序逻辑的核心中高效使用。

在简单的 Android 应用程序中,所有 3 个数据组都可以使用同一组数据 classes 实现,在复杂的应用程序中 - 它们可能因某种相互映射而不同。每个公司都可以指定一些模式来构建 classes 的层次结构。所以我一如既往地认为这里没有灵丹妙药。

实践中:

  • 根据您的 JSON,您必须为 "Transfer" 组构建特定的数据集 classes(我认为这是最明显的部分)。
  • 要持久化数据,有多种选择。这取决于您应用的用例。例如,这里没有要求将 "wind" 保存到单独的 table(与相应的 "Transfer" 数据 class 相关联)。如果有意义,您可以这样做。但是你也可以在这里选择最简单的模型——只有两个 tables "main_data"(除天气块之外的所有数据)和 "additional_data"(只有带有 main_table 外键的天气块) .比方说,你有风、雨的改造列表,而你在 SQLite 中只有 main_table 来保存这些数据列表。但这不是问题 - 在你的 Room 的 DAO 中应该有一些函数如何在你的 main_table 中保存你想要的所有数据。
  • 对于您的用例,您可以声明其他具有对您有效的结构的 classes(可能其中一些与您的 "Transfer" 数据相同 class es,可能不是)。您是否需要单独使用 "Wind" 或 "Rain" - 没问题。你声明你的 classes 并在 Room DAO 的请求中使用它作为返回值的类型(两个独立的函数到一个 SQLite table)。您可以在 classes 中声明对象列表作为 class 的字段,Room 可以使用 Relations 做到这一点。

.