[英]Multiple tables with same type of objects in Room database
I'm using Room as the database for the app. 我正在使用Room作为应用程序的数据库。 I have a scenario where an
Object
of a certain type needs to be stored in separate tables. 我有一个场景,其中某种类型的
Object
需要存储在单独的表中。 As an example, lets take the Object
called Book.java
举个例子,让我们拿一个名为
Book.java
的Object
Now, I want to have two SQL tables: 现在,我想要两个SQL表:
ignore any naming conventions for SQL DB please - this is just an example 请忽略SQL DB的任何命名约定 - 这只是一个例子
Problem 问题
Normally, one would just use @Entity(tableName = "Books_Read")
in the Book.java
class and have a DAO
class that will use that table name. 通常,人们只会在
Book.java
类中使用@Entity(tableName = "Books_Read")
并拥有一个将使用该表名的DAO
类。
The thing is; 事情是; how would I then be able to use the same
Book.java
class to store in the Books_To_Read
table? 那么我怎样才能使用相同的
Book.java
类存储在Books_To_Read
表中? Since I already defined @Entity(tableName = "Books_Read")
as part of the Book.java
class and I see no where to define the Books_To_Read
table for the Book.java
class 因为我已经将
@Entity(tableName = "Books_Read")
为Book.java
类的一部分,所以我看不到在哪里为Book.java
类定义Books_To_Read
表
The only solution I was able to come up with, which seems a little hackery and unnessasery, was to create a new class - let's call it BookToRead.java
that extends Book.java
and define @Entity(tableName = "Books_To_Read")
in the class. 我能够提出的唯一解决方案是创建一个新类 - 让我们称之为
BookToRead.java
,它扩展了Book.java
并定义了@Entity(tableName = "Books_To_Read")
。类。
Question 题
Is there a better way to do this or is this the expected way to handle it? 有没有更好的方法来做到这一点,或者这是处理它的预期方法?
Is this the expected way to handle it?
这是处理它的预期方式吗?
No . 不 。 It is a wrong approach.
这是一种错误的做法。 You should eliminate duplication of data for several reasons.
出于多种原因,您应该消除重复数据 。
It will cost storage space. 这将耗费存储空间。 As the size of database increases, this will began to become worse.
随着数据库大小的增加,这将开始变得更糟。
It will make the system complicated. 它会使系统变得复杂。 If you are updating a single field, You may have to perform the same action at different places.
如果要更新单个字段,则可能必须在不同位置执行相同的操作。 If you miss any one of them, the entire data will become inconsistent.
如果您错过了其中任何一个,整个数据将变得不一致。 It is possible to perform such operations as a single transaction.
可以执行诸如单个事务的操作。 But it is always better to keep the database structure clean.
但是保持数据库结构清洁总是更好。
Method 1: Introduce new tables 方法1:引入新表
You can store details of books in only one table say "Books"
. 您可以只在一个表中存储书籍的详细信息,例如
"Books"
。 "Books_To_Read"
or any other table should contain only the reference to the "Books"
table ( By using the id/ primary key in "Books"
table ). "Books_To_Read"
或任何其他表应该只包含参照"Books"
表( 通过在使用id /主键"Books"
表 )。 You can then use the JOIN
keyword to get the entire record at a single query. 然后,您可以使用
JOIN
关键字在单个查询中获取整个记录。
This method is preferred if each type (read and unread books in this case) has it's own set of fields ( Like the read_date, read_time for read books and wish_to_read for unread books ). 如果每种类型(在这种情况下是读取和未读书籍)都有自己的字段集( 如read_date,read_time用于读取书籍,wish_to_read用于未读书籍 ) ,则首选此方法。
Method 2: Introduce new field 方法2:引入新领域
You can simply add a new type which specifies the type. 您只需添加一个指定类型的新类型即可。 In this case, there are only two type(read and unread), a boolean field (something like
is_read
) will be fine. 在这种情况下,只有两种类型(读取和未读取),布尔字段(类似于
is_read
)就可以了。
This would be the easiest method. 这将是最简单的方法。 But this will work only if you just want to indicate which type the row belongs to.
但这只有在您只想指出该行所属的类型时才有效。 If you do need to store type specific data and you introduce additional fields for that purpose, remember that those fields will exists for others types too.
如果确实需要存储特定于类型的数据,并为此目的引入了其他字段,请记住这些字段也适用于其他类型。
This is how I eventually solved this problem: 这就是我最终解决这个问题的方法:
I added an ID to the Book.java
class that represents whether it has been read or not. 我在
Book.java
类中添加了一个ID,表示它是否已被读取。 Backed by an EnumType
that was either book_read
or book_unread
and then in my DAO
for "BooksDataTable"
I then just use a SQL query
to select
the ID
I want. 由一个是
book_read
或book_unread
的EnumType
支持,然后在我的DAO
为"BooksDataTable"
,然后我只使用SQL query
来select
我想要的ID
。 So by changing the query I can get either all the books_read
or books_to_read
or all_books
. 因此,通过更改查询,我可以获得所有
books_read
或books_to_read
或all_books
。 This way, there is no duplication of data and everything is in one table, without having to use JOIN
or OneToMany
relationships. 这样,没有重复的数据,所有内容都在一个表中,而不必使用
JOIN
或OneToMany
关系。
@OneToMany(mappedBy="book_id")
private Set<Book> book
I think this is best way to connecting two tables. 我认为这是连接两个表的最佳方法。 Try it and let me know your feed back.
尝试一下,让我知道您的反馈。 I will give anothor solution
我会给出一个解决方案
I was writing sample app when Ahamad gave his answer. 当Ahamad给出答案时,我正在编写示例应用程序。
Room provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite.
Room提供了一个覆盖SQLite的抽象层,允许流畅的数据库访问,同时利用SQLite的全部功能。
main idea is same as of to store Book data in one table and use the id of the book in other tables. 主要思想与将书籍数据存储在一个表格中相同,并在其他表格中使用书籍的ID。 have a look at my sample project
看看我的示例项目
result of logcat 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}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.