【问题标题】:Multiple tables with same type of objects in Room databaseRoom数据库中具有相同类型对象的多个表
【发布时间】:2018-06-25 01:22:41
【问题描述】:

我使用 Room 作为应用程序的数据库。我有一个场景,其中某种类型的Object 需要存储在单独的表中。举个例子,我们以Object 为例,称为Book.java

现在,我想要两个 SQL 表:

  • Books_Read
  • Books_To_Read

请忽略 SQL DB 的任何命名约定 - 这只是一个示例

问题

通常,在Book.java 类中使用@Entity(tableName = "Books_Read") 并有一个DAO 类将使用该表名。

问题是;然后我如何能够使用相同的 Book.java 类存储在 Books_To_Read 表中?因为我已经将@Entity(tableName = "Books_Read") 定义为Book.java 类的一部分,我看不到在哪里为Book.java 类定义Books_To_Read

我能想出的唯一解决方案是创建一个新类——我们称之为BookToRead.java,它扩展Book.java,并在类中定义@Entity(tableName = "Books_To_Read")

问题

有没有更好的方法来做到这一点,或者这是处理它的预期方法?

【问题讨论】:

  • 我的意思是如果它是同一个实体 - 那你为什么要为此使用不同的表呢? Imo 它应该是同一张表,但只有额外的列,如“to_read”或其他。
  • @rom4ek 你是对的。我在发布这个问题后不久就意识到了这一点。我最终通过添加一个表和一个新列来区分不同类型来解决它。
  • 我不确定这是否仅与这种特殊情况有关,但是在表格中有一个额外的字段/列来说明这本书是否被阅读过,不会做这项工作吗?为什么要将它们存储在不同的表中?
  • 我也有类似的问题。数据可能会在 24 小时后过时,所以我会在此时间后删除所有保存的数据。因此,生病删除天气我喜欢删除对象(删除存储在 obj 中的布尔变量)。因此我可能需要另一个表和/或共享首选项中的标志。目前也在使用房间。

标签: android sql database database-design android-room


【解决方案1】:
@OneToMany(mappedBy="book_id")
private Set<Book> book

我认为这是连接两个表的最佳方式。试试看,让我知道你的 回馈。我会给出另一个解决方案

【讨论】:

  • 这没有回答问题。
  • 你没看他的问题……哈哈
【解决方案2】:

这是预期的处理方式吗?

。这是一种错误的做法。出于多种原因,您应该消除数据重复

  • 这会消耗存储空间。随着数据库大小的增加,这 会开始变得更糟。

  • 这会使系统变得复杂。如果您要更新单个 字段,您可能必须在不同的地方执行相同的操作。 如果你错过其中任何一个,整个数据将变成 不一致。可以执行如下操作 单笔交易。但是最好保持数据库结构 干净。


解决方案

方法一:引入新表

您可以将书籍的详细信息存储在一张表中,例如"Books""Books_To_Read" 或任何其他表应仅包含对 "Books" 表的引用(通过使用 "Books" 表中的 id/ 主键)。然后,您可以使用 JOIN 关键字在一次查询中获取整条记录。

如果每种类型(在本例中为已读和未读书籍)都有自己的一组字段,则首选此方法(如 read_date、read_time 用于已读书籍,wish_to_read 用于未读书籍)。

方法二:引入新领域

您可以简单地添加一个指定类型的新类型。在这种情况下,只有两种类型(已读和未读),一个布尔字段(类似于is_read)就可以了。

这将是最简单的方法。但这仅在您只想指示该行属于哪种类型时才有效。如果您确实需要存储特定于类型的数据并且为此目的引入了其他字段,请记住这些字段也适用于其他类型。

【讨论】:

    【解决方案3】:

    Ahamad 给出答案时,我正在编写示例应用程序。

    Room 在 SQLite 之上提供了一个抽象层以允许 fluent 数据库访问,同时利用 SQLite 的全部功能。

    主要思想与将书籍数据存储在一个表中并在其他表中使用书籍的ID相同。 看看我的样本project

    logcat 的结果

    02-19 16:39:26.741 10520-10520/com.example.jingged.roomtest E/MainActivity: Book{id = 1 name = Book 0, author Author 0}
    02-19 16:39:26.741 10520-10520/com.example.jingged.roomtest E/MainActivity: Book{id = 2 name = Book 1, author Author 1}
    02-19 16:39:26.741 10520-10520/com.example.jingged.roomtest E/MainActivity: Book{id = 3 name = Book 2, author Author 2}
    02-19 16:39:26.741 10520-10520/com.example.jingged.roomtest E/MainActivity: Book{id = 4 name = Book 3, author Author 3}
    02-19 16:39:26.767 10520-10520/com.example.jingged.roomtest E/MainActivity: BookToRead Book{id = 3 name = Book 2, author Author 2}
    02-19 16:39:26.767 10520-10520/com.example.jingged.roomtest E/MainActivity: BookToRead Book{id = 4 name = Book 3, author Author 3}
    02-19 16:39:26.768 10520-10520/com.example.jingged.roomtest E/MainActivity: BooksRead Book{id = 1 name = Book 0, author Author 0}
    02-19 16:39:26.768 10520-10520/com.example.jingged.roomtest E/MainActivity: BooksRead Book{id = 2 name = Book 1, author Author 1}
    

    【讨论】:

    • 这只是复制相同的代码并仅更改表名吗?
    【解决方案4】:

    这就是我最终解决这个问题的方法:

    我在Book.java 类中添加了一个ID,表示它是否已被读取。由EnumType 支持,即book_readbook_unread 然后在我的DAO"BooksDataTable" 然后我只需使用SQL queryselect 我想要的ID。因此,通过更改查询,我可以获得所有books_readbooks_to_readall_books。这样,就没有数据重复,一切都在一个表中,而不必使用JOINOneToMany 关系。

    【讨论】:

      猜你喜欢
      • 2017-11-09
      • 2016-05-13
      • 2022-06-21
      • 1970-01-01
      • 2018-02-28
      • 1970-01-01
      • 1970-01-01
      • 2020-12-21
      • 2016-09-10
      相关资源
      最近更新 更多