如何在一个模型中添加两​​个表 class(房间)android studio

how to add two tables in one model class (Room) android studio

问题是:我正在从 API 获取新闻并将它们缓存在一个实体 (articles_table) 中(文章 class),所以我想添加另一个实体( bookmark_table) 具有相同的(文章)模型 class。

我想要内部文章模型class:

这可能吗?将两个表合二为一 class?或者有另一种方法可以做同样的事情?

     @Entity(tableName = "articles_table")
        data class Articles(
            @PrimaryKey(autoGenerate = true)
            val id: Int,
            val author: String,
            val date: String,
            val img: String,
            val source: String,
            val title: String,
            val url: String,
            val interest:String
        )

is this possible? to have two tables in one class?

不,@Entity 根据

将 class 定义为 table

Marks a class as an entity. This class will have a mapping SQLite table in the database. https://developer.android.com/reference/androidx/room/Entity

您可以将文章 Class 嵌入到另一个 @Entity class 中,并且实际上是第二个,几乎相同的结构,table。 例如:-

@Entity(tableName = "articles_bookmark_table", primaryKeys = ["id"])
data class BookMarkArticles(
    @Embedded
    val articles: Articles
)
  • 注意当Embedding the Primary Key不包括在内,因此需要定义它。
  • 我认为这是一种不稳定的方法,因为它可能会导致对不明确的列产生混淆,因为列名是相同的。

但是,我建议您不要使用 2 个基本相同的 table,而只需添加一个指示器(布尔值)来确定它是否是书签行。例如:-

@Entity(tableName = "articles_table")
data class Articles(
    @PrimaryKey //<<<<<<<<<< autoGenerate removed
    val id: Int? = null, //<<<<<<<<<< defaults to null so if not provided auto generates id
    val author: String,
    val date: String,
    val img: String,
    val source: String,
    val title: String,
    val url: String,
    val interest:String,
    val bookmark:Boolean //<<<<<<<<<< ADDED to distinguish bookmark row or not
)

将 2 table 与嵌入式一起使用会在 inserting/extracting 时引入细微差别,如下面的演示。

该演示使用略微修改的 Articles 和 BookMarkArticles 以及作为 ArticlesV2 的第 2 篇文章来同时展示这两种方式。

所以文章是:-

@Entity(tableName = "articles_table")
data class Articles(
    @PrimaryKey
    val id: Int? = null,
    val author: String,
    val date: String,
    val img: String,
    val source: String,
    val title: String,
    val url: String,
    val interest:String
)

-即id 允许为 null,因此当未提供时将自动生成 id。

BookMarkArticles(嵌入文章)是:-

@Entity(tableName = "articles_bookmark_table", primaryKeys = ["id"])
data class BookMarkArticles(
    @Embedded
    val articles: Articles
)

ArticlesV2(两种类型合二为一table)是:-

@Entity(tableName = "articles_v2_table")
data class ArticlesV2(
    @PrimaryKey
    val id: Int? = null,
    val author: String,
    val date: String,
    val img: String,
    val source: String,
    val title: String,
    val url: String,
    val interest:String,
    val bookmark:Boolean
)

Dao 是:-

@Insert
abstract fun insert(articles: Articles): Long
@Insert
abstract fun insert(bookMarkArticles: BookMarkArticles): Long
@Insert
abstract fun insert(articlesV2: ArticlesV2): Long

@Query("SELECT * FROM articles_table")
abstract fun getAllArticles(): List<Articles>
@Query("SELECT * FROM articles_bookmark_table")
abstract fun getAllBookmarkedArticles(): List<BookMarkArticles>
@Query("SELECT * FROM articles_v2_table WHERE bookmark=:bookmarked")
abstract fun getAllArticleV2s(bookmarked: Boolean): List<ArticlesV2>

在 Activity 中是以下代码:-

    db = TheDatabase.getInstance(this)
    dao = db.getDao()

    dao.insert(Articles(author = "Fred",date = "2021-01-01",img = "MyImage", title = "MyTitle", url = "MyUrl",source = "MySource",interest = "MyInterest"))
    dao.insert(Articles(author = "Bert",date = "2021-01-01",img = "MyImage", title = "MyTitle", url = "MyUrl",source = "MySource",interest = "MyInterest"))
    dao.insert(BookMarkArticles(Articles(author = "Fred",date = "2021-01-01",img = "MyImage", title = "MyTitle", url = "MyUrl",source = "MySource",interest = "MyInterest")))
    dao.insert(BookMarkArticles(Articles(author = "Bert",date = "2021-01-01",img = "MyImage", title = "MyTitle", url = "MyUrl",source = "MySource",interest = "MyInterest")))
    dao.insert(ArticlesV2(author = "Fred",date = "2021-01-01",img = "MyImage", title = "MyTitle", url = "MyUrl",source = "MySource",interest = "MyInterest",bookmark = false))
    dao.insert(ArticlesV2(author = "Bert",date = "2021-01-01",img = "MyImage", title = "MyTitle", url = "MyUrl",source = "MySource",interest = "MyInterest",bookmark = false))
    dao.insert(ArticlesV2(author = "Fred",date = "2021-01-01",img = "MyImage", title = "MyTitle", url = "MyUrl",source = "MySource",interest = "MyInterest",bookmark = true))
    dao.insert(ArticlesV2(author = "Bert",date = "2021-01-01",img = "MyImage", title = "MyTitle", url = "MyUrl",source = "MySource",interest = "MyInterest",bookmark = true))

    for(a: Articles in dao.getAllArticles()) {
        Log.d("ARTICLEINFO","(not bookmark) Author is ${a.author} ID is ${a.id} etc")
    }
    for(b: BookMarkArticles in dao.getAllBookmarkedArticles()) {
        Log.d("ARTICLEINFO","(bookmark) Author is ${b.articles.author} ID is ${b.articles.id} etc")
    }
    for(a: ArticlesV2 in dao.getAllArticleV2s(false)) {
        Log.d("ARTICLEV2INFO","(not bookmark) Author is ${a.author} ID is ${a.id} etc BOOKMARK Flag is ${a.bookmark}")
    }
    for(a: ArticlesV2 in dao.getAllArticleV2s(true)) {
        Log.d("ARTICLEV2INFO","(bookmark) Author is ${a.author} ID is ${a.id} etc BOOKMARK Flag is ${a.bookmark}")
    }
  • 请注意 BookMarkArticles 是通过 Articles 对象构造的,并且在提取 BookMarkArticles 时它具有嵌入的 Articles 对象的细微差别。

日志中的结果:-

2021-09-01 16:32:09.844 D/ARTICLEINFO: (not bookmark) Author is Fred ID is 1 etc
2021-09-01 16:32:09.845 D/ARTICLEINFO: (not bookmark) Author is Bert ID is 2 etc


2021-09-01 16:32:09.847 D/ARTICLEINFO: (bookmark) Author is Fred ID is 1 etc
2021-09-01 16:32:09.847 D/ARTICLEINFO: (bookmark) Author is Bert ID is 2 etc


2021-09-01 16:32:09.849 D/ARTICLEV2INFO: (not bookmark) Author is Fred ID is 1 etc BOOKMARK Flag is false
2021-09-01 16:32:09.849 D/ARTICLEV2INFO: (not bookmark) Author is Bert ID is 2 etc BOOKMARK Flag is false
2021-09-01 16:32:09.851 D/ARTICLEV2INFO: (bookmark) Author is Fred ID is 3 etc BOOKMARK Flag is true
2021-09-01 16:32:09.851 D/ARTICLEV2INFO: (bookmark) Author is Bert ID is 4 etc BOOKMARK Flag is true

我找到了一个简单的解决方案:

第 class 条 articles_table

@Entity(tableName = "articles_table")
data class Article(
    @PrimaryKey(autoGenerate = true)
    val id: Int,
    val author: String,
    val date: String,
    val img: String,
    val source: String,
    val title: String,
    val url: String,
    val interest:String
): Serializable

并用 articles_bookmark_table

创建了 BookmarkArticle class
@Entity(tableName = "articles_bookmark_table", primaryKeys = ["id"])
data class BookmarkArticles(
    @Embedded
    val article: Article
)

然后创建了 BookmarkArticleDao:

@Dao
interface BookmarkArticlesDao {

    @Query("SELECT * FROM articles_bookmark_table")
    fun getAllArticles(): List<Article>

    @Insert(entity = BookmarkArticles::class, onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertArticles(article: Article)

    @Delete(entity = BookmarkArticles::class)
    suspend fun deleteArticles(article: Article)

}
  • @Query 我从 articles_bookmark_table
  • 获取文章列表
  • @Insert 和@Delete 我刚刚添加了实体 = BookmarkArticles::class 所以它在 articles_bookmark_table
  • 中删除和插入书签

对我来说效果很好