微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Android 存储嵌套的 JSON 对象从 Api 调用到 Sqlite

如何解决Android 存储嵌套的 JSON 对象从 Api 调用到 Sqlite

如何在 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"
          }
        }
      ],"alternateLink": "https://classroom.google.com/c/MTk2MDE0NjA1OTE0/p/MjQ2NDE5MjY1NjQy","creationTime": "2021-01-25T10:41:45.094Z","updateTime": "2021-01-25T10:41:44.260Z",],"nextPagetoken": "GkUSQxJBCLHA5Pr4LhI4Cg5iDAi2pfD_BRDAoOKzAQoOYgwItqXw_wUQgMCNtwEKCgiAgICg29jhsFoKCgiAgIDgwu223Hk"
}

这是公告对象的一部分,但有些没有材质对象,如上所示。问题是并不是所有的公告都有 Material 对象,所以一个公告对象最多可以有 20 个材质对象。

我的数据模型如下所示:

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

请大家...

这里请不要负能量,我只是想不出这里的解决方

解决方法

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

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

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

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

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

公告(courseId、id、text、...)

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

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

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

有几种可能:

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

第一个选项是逻辑上偏爱并提供最佳用户体验。

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

SELECT * FROM Material WHERE announcementId = this.id

它会返回与个人 Material 相关联的 Announcement 列表。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。