当前位置: 首页 > 知识库问答 >
问题:

如何在Room持久性库中使用外键

邰宇
2023-03-14

我正在使用android的房间持久性库,如果有人能帮助我使用外键,如何通过使用外键获取数据,我将不胜感激。

共有3个答案

姬俊能
2023-03-14

@ForeignKey注释在获取数据时不用于定义关系,而是在修改数据时用于定义关系。为了从房间数据库中获取关系数据,Google建议使用@relationship以及@Embedded注释。

如果你感兴趣的话,你可以在这里查看我的答案以获得更多解释。

鞠征
2023-03-14

这里介绍如何在Android Jetpack Room中定义和访问一对多(外键)关系。这里的实体是ArtistAlbum,外键是Album。艺术家

@Entity
data class Artist(
    @PrimaryKey
    val id: String,
    val name: String
)

@Entity(
    foreignKeys = [ForeignKey(
        entity = Artist::class,
        parentColumns = arrayOf("id"),
        childColumns = arrayOf("artist"),
        onDelete = ForeignKey.CASCADE
    )]
)
data class Album(
    @PrimaryKey
    val albumId: String,
    val name: String,
    @ColumnInfo(index = true)
    val artist: String
)

然后是嵌入式对象(阅读Android官方文档:定义对象之间的关系)

data class ArtistAndAlbums(
    @Embedded
    val artist: Artist,
    @Relation(
        parentColumn = "id",
        entityColumn = "artist"
    )
    val albums: List<Album>
)

最后是DAO

@Dao
interface Library {
    @Insert
    suspend fun save(artist: Artist)

    @Insert
    suspend fun save(vararg album: Album)

    @Transaction
    @Query("SELECT * FROM artist")
    suspend fun getAll(): List<ArtistAndAlbums>

    @Transaction
    @Query("SELECT * FROM artist WHERE id = :id")
    suspend fun getByArtistId(id: String): ArtistAndAlbums
}

尝试这个,(所有这些操作都发生在协程中)

// creating objects
val artist = Artist(id="hillsongunited", name="Hillsong United" )
val artist2 = Artist(id="planetshakers", name="Planet Shakers" )

val album1 = Album(albumId = "empires", name = "Empires", artist = artist.id)
val album2 = Album(albumId = "wonder", name = "Wonder", artist = artist.id)
val album3 = Album(albumId = "people", name = "People", artist = artist.id)

val album4 = Album(albumId = "rain", name = "Rain", artist = artist2.id)
val album5 = Album(albumId = "itschristmas", name = "Its Christmas", artist = artist2.id)
val album6 = Album(albumId = "overitall", name = "Over It All", artist = artist2.id)

// saving to database
SongDatabase.invoke(applicationContext).library().save(artist)
SongDatabase.invoke(applicationContext).library().save(artist2)
SongDatabase.invoke(applicationContext).library().save(album1, album2, album3, album4, album5, album6)

注销所有艺术家

val all = SongDatabase.invoke(applicationContext).library().getAll()
Log.d("debug", "All Artists $all ")

D/debug: All Artists [ArtistAndAlbums(artist=Artist(id=hillsongunited, name=Hillsong United), albums=[Album(albumId=empires, name=Empires, artist=hillsongunited), Album(albumId=wonder, name=Wonder, artist=hillsongunited), Album(albumId=people, name=People, artist=hillsongunited)]), ArtistAndAlbums(artist=Artist(id=planetshakers, name=Planet Shakers), albums=[Album(albumId=rain, name=Rain, artist=planetshakers), Album(albumId=itschristmas, name=Its Christmas, artist=planetshakers), Album(albumId=overitall, name=Over It All, artist=planetshakers)])]

注销特定艺术家的专辑,

val hillsongAlbums = SongDatabase.invoke(applicationContext).library().getByArtistId(artist.id)
Log.d("debug", "Albums by artist ID: $hillsongAlbums ")

D/debug: Albums by artist ID: ArtistAndAlbums(artist=Artist(id=hillsongunited, name=Hillsong United), albums=[Album(albumId=empires, name=Empires, artist=hillsongunited), Album(albumId=wonder, name=Wonder, artist=hillsongunited), Album(albumId=people, name=People, artist=hillsongunited)]) 
鞠鸿雪
2023-03-14

以下是为未来读者总结的上述文章:

Kotlin中的外键语法为

@Entity(foreignKeys = arrayOf(ForeignKey(entity = ParentClass::class,
                    parentColumns = arrayOf("parentClassColumn"),
                    childColumns = arrayOf("childClassColumn"),
                    onDelete = ForeignKey.CASCADE)))

Java中的外键语法为:

@Entity(foreignKeys = {@ForeignKey(entity = ParentClass.class,
    parentColumns = "parentClassColumn",
    childColumns = "childClassColumn",
    onDelete = ForeignKey.CASCADE)
})

注意:foreignKeys是一个数组,因此在Java中,将@ForeignKey元素包含在{和}中

有关更多信息,请参阅官方文档。https://developer.android.com/reference/androidx/room/ForeignKey

 类似资料:
  • 下面是Kotlin中的类: 但当我试图运行应用程序时,它立即崩溃。以下是崩溃日志: 类似乎不是自动生成的。我检查了从codelab下载的原始java应用程序,发现是自动生成的。

  • 我想使用预先填充的数据库的房间,但我不明白如何告诉房间在哪里找到我的数据库。 现在我将它放在中,当我为房间数据库创建实例时,我是这样创建的: 这样一来,我认为它每次都在创建一个新的数据库,或者说,它没有使用预填充的数据库。 我怎样才能找到我的数据库?

  • 我试图通过新的android room库更新我的数据库,但它不起作用。这就是我的方法 主要活动。JAVA CarViewModel。JAVA 卡ao.java 我做了调试,新数据出现并调用viewModel。updateItems(list)方法。提前谢谢!

  • 我想在运行时生成的SQLite数据库上运行查询(而不是@Dao中的标准compiletime查询)。例如,我可能想在SQLite数据库中搜索一个文本列,看看它是否包含N个长度的列表中的所有单词。在原始SQLITE中,N为3的查询如下所示: 我尝试过生成并传递查询的结尾,而不是仅仅传递变量。例如: 在@Dao中: 这似乎对我不起作用。你知道如何让运行时生成的查询与Room一起工作吗? 附言:

  • 当我运行程序时。我在我的LogCat中得到“Migration Ended”日志,但当我再次尝试access数据库时,它给我以下错误。 我完全不知道这个“整数”要到哪里去。我尝试了卸载,使缓存无效和任何其他密切相关的解决方案。知道这是怎么回事吗?如果你刚安装应用程序,它的工作非常好。只有在迁移后才会出现错误。根据我的日志猫,所有迁移步骤似乎都已完成,但仍然显示迁移没有正确处理。

  • 问题内容: 我想知道如何禁用Redis的持久性。这里提到了这样做的可能性:http : //redis.io/topics/persistence。我的意思是和那里描述的完全一样。任何帮助将不胜感激! 问题答案: 要禁用Redis中的 所有 数据持久性,请执行以下操作: 通过将配置指令设置为(默认值)来禁用AOF 通过禁用(注释掉)所有配置指令来禁用RDB快照(默认情况下定义了3个) 这些配置指令