日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

联合查询是要多创建一个实体类么_[译] 如何用 Room 处理一对一,一对多,多对多关系?...

發布時間:2024/10/12 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 联合查询是要多创建一个实体类么_[译] 如何用 Room 处理一对一,一对多,多对多关系?... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文作者:Florina Muntenescu 原文地址: medium.com/androiddeve… 譯者:秉心說
譯者說:最近在做一款 Rss 閱讀器,使用 Room 存儲訂閱源以及其中的文章,這就是一個典型的 一對多 關系。正好通過此文詳細了解 @Relation 注解的使用。

將數據拆分為相關聯的表,并以有意義的方式將數據組合在一起 是設計關系型數據庫的重要部分。從 Room 2.2 (現已穩定)開始,通過 @Relation 注解,我們支持了表之間所有可能的關系:一對一,一對多,多對多 。

一對一

假如我們生活在一個(悲傷的)世界,每個人只能擁有一條狗,并且每條狗也只能有一個主人。這就是一對一關系。為了在關系型數據庫中 表示這一關系,我們創建了兩張表,Dog 和 Owner 。Dog 表持有 owner id 的引用,Owner 表持有 dog id 的引用。在 Room 中,我們創建這樣兩個實體類:

@Entity data class Dog(@PrimaryKey val dogId: Long,val dogOwnerId: Long,val name: String,val cuteness: Int,val barkVolume: Int,val breed: String ) @Entity data class Owner(@PrimaryKey val ownerId: Long, val name: String)

我們要在頁面上顯示所有的狗狗和它們的主人,為此,我們創建了一個數據類 DogAndOwner :

data class DogAndOwner(val owner: Owner,val dog: Dog )

要通過 Sqlite 完成此次查詢,我們需要:

  • 進行兩次查詢,先查詢出所有的主人,然后在根據主人的 owner id 查詢出所有的狗
  • 處理對象映射
  • SELECT * FROM Owner SELECT * FROM DogWHERE dogOwnerId IN (ownerId1, ownerId2, …)

    通過 Room 來得到 List<DogAndOwner> ,我們不需要自己實現兩次查詢和對象映射,僅僅通過 @Relation 注解即可。

    在上面的例子中,由于 Dog 擁有主人的信息,所有在 dog 變量上添加 @Relation 注解:指定 owner 表中的 ownerId 和 dog 表中的 dogOwnerId 是相對應的。

    data class DogAndOwner(@Embedded val owner: Owner,@Relation(parentColumn = "ownerId",entityColumn = "dogOwnerId")val dog: Dog )

    Dao 可以簡化如下:

    @Transaction @Query("SELECT * FROM Owner") fun getDogsAndOwners(): List<DogAndOwner>

    注意:由于 Room 會在后臺自動為我們執行這兩次查詢,所以要添加 @Transaction 注解以保證原子性。

    一對多

    假設一個主人可以擁有多條狗狗 (Yeah !) ,Owner 和 Dog 之間是一對多的關系。之前定義的數據庫結構不需要發生任何變化,我們仍然使用之前的表,因為相關聯的鍵已經在表中了。

    現在,為了展示主人和他的狗狗們,我們需要創建一個新的數據類:

    data class OwnerWithDogs(val owner: Owner,val dogs: List<Dog> )

    為了避免兩次查詢,我們給 List<Dog> 添加 @Relation 注解來定義 Dog 和 Owner 之間的一對多關系。

    data class OwnerWithDogs(@Embedded val owner: Owner,@Relation(parentColumn = "ownerId",entityColumn = "dogOwnerId")val dogs: List<Dog> )

    Dao 是這樣的。

    @Transaction @Query("SELECT * FROM Owner") fun getDogsAndOwners(): List<OwnerWithDogs>

    多對多

    現在假設我們生活在一個完美的世界,每個主人可以擁有多條狗,每條狗也可以有多個主人。要對此關系進行建模,僅僅通過 Dog 表和 Owner 表是不夠的。由于一條狗可能有多個主人,所以同一個 dogId 可能需要多條數據,以匹配不同的主人。但是在 Dog 表中,dogId 是主鍵,我們不能插入多個 id 相同,主人不同的狗狗。為了解決這一問題,我們需要額外創建一個存儲 (dogId,ownerId) 的 關聯表 (也稱為交叉引用表) 。

    @Entity(primaryKeys = ["dogId", "ownerId"]) data class DogOwnerCrossRef(val dogId: Long,val ownerId: Long )

    假設現在僅僅只通過 Sqlite 來所有的主人和他們的狗:List<OwnerWithDogs> ,我們需要兩次查詢:獲取所有的主人,聯表查詢 Dog 表和 DogOwnerCrossRef 表。

    SELECT * FROM Owner SELECTDog.dogId AS dogId,Dog.dogOwnerId AS dogOwnerId,Dog.name AS name,_junction.ownerId FROMDogOwnerCrossRef AS _junction INNER JOIN Dog ON (_junction.dogId = Dog.dogId)

    用 Room 實現的話,我們需要更新 OwnerWithDogs 實例類,告訴 Room 要為了獲取對應的所有狗狗,要關聯表 DogOwnerCrossRef 。通過 Junction 來引用表。

    在 Dao 中,通過查詢 Owner 來返回正確的數據類。

    @Transactionhttps://youtu.be/_aJsh6P00c0 @Query("SELECT * FROM Owner") fun getOwnersWithDogs(): List<OwnerWithDogs>

    高級用法示例

    當使用 @Relation 注解時,Room 根據被注解的屬性類型來推斷使用哪個實體類。例如,到目前為止,我們給 Dog 或 List<Dog> 添加了注解,這就告訴了 Room 要使用哪個類,要查詢哪些字段。

    如果我們想返回一個其他對象,例如 Pup,它不是一個實體但是包含了一些字段。我們可以通過 @Relation 注解指定要使用的實體。

    data class Pup(val name: String,val cuteness: Int = 11 ) data class OwnerWithPups(@Embedded val owner: Owner,@Relation(parentColumn = "ownerId",entity = Dog::class,entityColumn = "dogOwnerId")val dogs: List<Pup> )

    如果我們指向返回實體類的指定字段,就需要通過 @Relation 注解的 projection 屬性來指定。例如,我們指向獲取 OwnerWithDogs中所有狗狗的名字,因此我們需要返回的是 List<String> 。而 Room 無法推斷這些字符串代表的是名字還是品種,所有需要我們通過 projection 指定。

    data class OwnerWithDogs(@Embedded val owner: Owner,@Relation(parentColumn = "ownerId",entity = Dog::class,entityColumn = "dogOwnerId",projection = ["name"])val dogNames: List<String> )

    如果你想在 dogOwnerId 和 ownerId 之間定義更加嚴格的關系,獨立于你所創建的任何關系,可以在這些字段之間添加 ForeignKey 約束。請記住,SQLite 外鍵定義索引,并且可以具有級聯觸發器來更新或刪除表中的條目。因此,請根據是否希望在數據庫中使用這種功能來決定是否要使用外鍵。

    無論你需要一對一,一對多,還是多對多的支持,Room 都可以通過 @Relation 注釋滿足你。

    總結

    以上是生活随笔為你收集整理的联合查询是要多创建一个实体类么_[译] 如何用 Room 处理一对一,一对多,多对多关系?...的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。