【问题标题】:Android store nested JSON Objects from Api call to SqliteAndroid 存储从 Api 调用到 Sqlite 的嵌套 JSON 对象
【发布时间】:2021-05-17 04:18:30
【问题描述】:

如何将具有其他对象作为实例变量的对象存储在 android SQLite 数据库中。

基本上,我从 Rest Api 调用得到的 JSON 响应看起来像:

{
  "announcements": [
    {
      "courseId": "196014605914",
      "id": "269865109791",
      "text": "Ignore the previous link. Join the already started CHM 112",
      "state": "PUBLISHED",
      "alternateLink": "https://classroom.google.com/c/MTk2MDE0NjA1OTE0/p/MjY5ODY1MTA5Nzkx",
      "creationTime": "2021-02-08T09:18:05.420Z",
      "updateTime": "2021-02-08T09:18:05.415Z",
      "creatorUserId": "101562079220031604157"
    },
    {
      "courseId": "196014605914",
      "id": "246419265642",
      "text": "Note2",
      "materials": [
        {
          "driveFile": {
            "driveFile": {
              "id": "1CjL0RV7PdcIrrRWii1ApUown3YoyEKTx",
              "title": "HYDROCARBONS2-C-C, C=C AND ALKYNES.pdf",
              "alternateLink": "https://drive.google.com/open?id=1CjL0RV7PdcIrrRWii1ApUown3YoyEKTx",
              "thumbnailUrl": "https://drive.google.com/thumbnail?id=1CjL0RV7PdcIrrRWii1ApUown3YoyEKTx&sz=s200"
            },
            "shareMode": "VIEW"
          }
        }
      ],
 "state": "PUBLISHED",
      "alternateLink": "https://classroom.google.com/c/MTk2MDE0NjA1OTE0/p/MjQ2NDE5MjY1NjQy",
      "creationTime": "2021-01-25T10:41:45.094Z",
      "updateTime": "2021-01-25T10:41:44.260Z",
      "creatorUserId": "101562079220031604157"
    },
  ],
  "nextPageToken": "GkUSQxJBCLHA5Pr4LhI4Cg5iDAi2pfD_BRDAoOKzAQoOYgwItqXw_wUQgMCNtwEKCgiAgICg29jhsFoKCgiAgIDgwu223Hk"
}

这是 Announcement 对象的一部分,但有些没有如上所示的 Material 对象。问题不是所有的 Announcement 都有 Material 对象,而且一个 Announcement 对象最多可以有 20 个 Material 对象。

我的数据模型如下所示:

public class CourseDetailsItem{
    private final String message;
    private final Long time;
    private final String author;
    private final List<Material> materials;

//... Appropriate getters and setters

//Material.java
public class Material{
    private final String label;
    private final String link;

//... Appropriate getters and setters

存储对象以供离线使用的最佳方式是什么?

在我的 DbHelper 类中我很困惑

SQLiteDatabase db = this.getWritableDatabase();
        String CREATE_COURSE_TABLE = "CREATE TABLE IF NOT EXISTS _"+courseId+" ("+ ID +" INTEGER PRIMARY KEY," + MESSAGE + " TEXT,"+ TIME + " INTEGER," + AUTHOR + " TEXT," + LABEL + " TEXT," + LINK + " TEXT"+")";
        db.execSQL(CREATE_COURSE_TABLE);
        ContentValues values = new ContentValues();
        values.put(MESSAGE, courseDetailsItem.getMessage());
        values.put(TIME, courseDetailsItem.getTime());
        values.put(AUTHOR, courseDetailsItem.getAuthor());
        //values.put(); HERE HOW DO I STORE MATERIAL OBJECT
        //Considering the fact that Material Object could be upto Twenty for each  of my entry

请大家...

请不要在这里有负能量,我只是无法在这里找到解决方案

【问题讨论】:

    标签: android sqlite pojo jsonschema2pojo


    【解决方案1】:

    最好或最直观的方法是在关系 SQLite 数据库中反映它们的关系。

    这意味着您将拥有一个 Announcement 表和一个 Material 表。

    Material 表中,您需要添加一个“外键”,其主ID 为它所指的Announcement。这样您就可以为Announcement 存储0...n Materials。您的Announcement 模型/表不需要更改,可以保持原样。

    注意:据我所知 SQLite 不支持真正的“外键”定义。这还不错,因为它只是关于基于主键从一个表到另一个表的“指针”的概念。在一个真实的、成熟的数据库中,它将对其进行评估并确保基于它的数据完整性。这种严格性并不总是需要或想要的,因此在 SQLite 中不支持 - 使其更轻量级。您还可以使用正确编写的代码确保相同的数据完整性。

    那么您将有两个如下所示的表:

    公告(courseId、id、文本...)

    材料(announcementId、id、title、alternateLink、...)

    编辑:这也称为OneToMany 关系。当您寻找“在关系数据库中建模 OneToMany 关系”时,您会发现很多资源对其进行了更详细的解释。

    在存储Announcement 时,您还将“简单”地将Material 对象存储在它们的表中。在这里,您可以评估是否要保持强大的数据完整性并希望将所有 AnnouncementMaterial 对象存储在一个事务中,或者是否不需要如此严格并将其存储在不同的事务中.

    有几种可能:

    • 单个 Announcement 对象与其所有 Materials 一起存储在一个事务中
    • 所有Announcement 对象与所​​有Materials 一起存储在一个事务中
    • 所有Announcement对象都存储在一个事务中,然后所有Material对象都存储在一个事务中

    第一个选项是逻辑上更喜欢并会提供最佳的用户体验。

    当从数据库加载Announcements 时,您可以决定是eagerly 还是lazy 加载Materials 列表。查询应如下所示:

    SELECT * FROM Material WHERE announcementId = this.id.

    它将返回与个人 Announcement 关联的 Materials 列表。

    【讨论】:

    • 我只想非常感谢您的时间和关注,如果我遇到困难(试图实施解决方案),请在这里发表评论,但我非常感谢。跨度>
    • 我很高兴答案对您有所帮助,并为您提供了寻找的方向。当然只是发表评论,我们会看看我能提供什么帮助。另外我想补充的是,您正在寻找的是 OneToMany 关系 - 当您搜索它时,您应该会找到很多有用的资源。另外关于外键:起初,SQLite 不支持它可能听起来很糟糕,但老实说,它并不那么重要(在客户端)。通过仔细编写代码,即使没有正确的外键验证,您也可以确保数据是一致的。因此,您只需要确保所有材料
    • 对象也将被删除,当相应的 Announcement 对象被删除时。为避免将存储没有链接的 Announcement 对象的 Material 对象。我相信当你用谷歌搜索它时也会解释这一点 - 否则请随时在 cmets 中告诉我。祝你好运,我相信你会成功的!)
    • 明白,我已经能够实现了。非常感谢
    猜你喜欢
    • 2015-02-02
    • 2018-04-27
    • 1970-01-01
    • 2014-03-07
    • 2021-01-02
    • 1970-01-01
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多