android ROOM kotlin官方文檔完全學習

android ROOM kotlin官方文檔完全學習2.6

使用 Room 將數據保存到本地數據庫 | Android Developers (google.cn)

一、簡介

1.1 引入
dependencies {def room_version = "2.6.1"implementation "androidx.room:room-runtime:$room_version"//如下三選一annotationProcessor "androidx.room:room-compiler:$room_version"kapt "androidx.room:room-compiler:$room_version"ksp "androidx.room:room-compiler:$room_version"// optional - RxJava2 support for Roomimplementation "androidx.room:room-rxjava2:$room_version"// optional - RxJava3 support for Roomimplementation "androidx.room:room-rxjava3:$room_version"// optional - Guava support for Room, including Optional and ListenableFutureimplementation "androidx.room:room-guava:$room_version"// optional - Test helperstestImplementation "androidx.room:room-testing:$room_version"// optional - Paging 3 Integrationimplementation "androidx.room:room-paging:$room_version"
}
1.2 三大組件
  • DataBase,用于保存數據庫并作為應用持久性數據底層連接的主要訪問點。
  • Entity,用于表示應用的數據庫中的表。
  • DAO(數據訪問對象),為您的應用提供在數據庫中查詢、更新、插入和刪除數據的方法。
1.3 快速示例
1.3.1 定義User類

定義User數據實體。每個實例代表數據庫user表的一行。

@Entity
data class User(@PrimaryKey val uid: Int,@ColumnInfo(name = "first_name") val firstName: String?,@ColumnInfo(name = "last_name") val lastName: String?
)

詳細使用參考第二章【使用Room實體定義數據】。

1.3.2 數據訪問對象(DAO)

用來操控user表的數據交互的方法。

@Dao
interface UserDao {@Query("SELECT * FROM user")fun getAll(): List<User>@Query("SELECT * FROM user WHERE uid IN (:userIds)")fun loadAllByIds(userIds: IntArray): List<User>@Query("SELECT * FROM user WHERE first_name LIKE :first AND " +"last_name LIKE :last LIMIT 1")fun findByName(first: String, last: String): User@Insertfun insertAll(vararg users: User)@Deletefun delete(user: User)
}

詳細使用參考第三章【使用DAO訪問數據】。

1.3.3 數據庫

作為應用對持久性數據的主要訪問點。幾個條件如下:

  • 使用@Database注解,列出所有的entities。

  • 必須抽象類,繼承自RoomDatabase。

  • 每一個DAO類,都需要一個定義一個零參數的抽象函數,返回DAO類的實例。

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {abstract fun userDao(): UserDaocompanion object {private var instance:AppDatabase? = nullprivate const val DATA_BASE_NAME = "app"private val lock = Any()/*** 調用單例數據庫*/val db : AppDatabaseget() {if (instance == null) {synchronized(lock) {if (instance == null) {instance = Room.databaseBuilder(Globals.app,AppDatabase::class.java,DATA_BASE_NAME)//.enableMultiInstanceInvalidation() 多進程啟用 todo.build()}}}return instance!!}}
}//使用的方法:
val userDao = AppDatabase.db().userDao()
val users: List<User> = userDao.getAll()

二、使用 Room 實體定義數據

2.1 實體詳解(@Entity, tableName)
@Entity(tableName = "users")
data class User(@PrimaryKey val id: Int,val firstName: String?,val lastName: String?
)

必須是public或者有get,set函數。定義為每一列。

類名就是就是數據表名,可以通過@entity里面的tableName修改。

字段名可以通過ColumnInfo的name修改。

表和列名都不區分大小寫。

2.2 主鍵(@PrimaryKey, autoGenerate)

必須定義主鍵,并使用@PrimaryKey注解。

@PrimaryKey val id: Int

由于默認是@PrimaryKey(autoGenerate = false)是false,所以必須自行管理id的唯一性,所以一般情況,我們需要設置為true。

2.3 復合主鍵(@Entity primaryKeys)
@Entity(primaryKeys = ["firstName", "lastName"])
data class User(val firstName: String?,val lastName: String?
)

如果您需要通過多個列的組合對實體實例進行唯一標識,則可以通過列出@Entity primaryKeys屬性中的以下列定義一個復合主鍵。

2.4 忽略字段(@Ignore,@Entity ignoredColumns)
@Entity
data class User(@PrimaryKey val id: Int,val firstName: String?,val lastName: String?,@Ignore val picture: Bitmap?
)

如果是繼承,想忽略父類里面的字段,通過@Entity(ignoredColumns = [ ])處理:

open class User {var picture: Bitmap? = null
}@Entity(ignoredColumns = ["picture"])
data class RemoteUser(@PrimaryKey val id: Int,val hasVpn: Boolean
) : User()

三、使用DAO訪問數據

可以定義為接口或者抽象類。使用@Dao進行注解。示例:

@Dao
interface UserDao {@Insertfun insertAll(vararg users: User)@Deletefun delete(user: User)@Query("SELECT * FROM user")fun getAll(): List<User>
}

有2種方式定義函數:

  • 3.1 不用編寫SQL代碼,實現插入更新刪除數據庫的行。
  • 3.2 自行編寫SQL查詢
3.1 便捷方法
Insert
@Dao
interface UserDao {@Insert(onConflict = OnConflictStrategy.REPLACE) //遇到有數據就替換,可以選擇ABORT,IGNOREfun insertUsers(vararg users: User)@Insertfun insertBothUsers(user1: User, user2: User)@Insertfun insertUsersAndFriends(user: User, friends: List<User>)
}

自己可以追加返回值,單入參就返回long型的rowId。多入參就定義返回值,數組型的rowId。TODO驗證是需要定義還是自行追加。

Update
@Dao
interface UserDao {@Updatefun updateUsers(vararg users: User)
}

可以追加返回值,指示成功更新的行數。TODO驗證是否會優先插入。

現在Insert和Update都只有三個OnConflictStrategy可選,REPLACE,IGNORE和ABORT。

Delete
@Dao
interface UserDao {@Deletefun deleteUsers(vararg users: User)
}

可以刪除1個或者多個。會根據主鍵去刪除,如果沒有相同主鍵的行,就不會有任何改變。可以追加返回值,返回的是int的刪除行數。

3.2 復雜方法(Query)

不要認為query就是查詢了。@Query注解,可以自定義SQL語句。有個優點是編譯就會報錯來提示你。

簡單查詢
@Query("SELECT * FROM user")
fun loadAllUsers(): Array<User>

查詢所有User對象。

返回表中多列的子集
  • 通過定義一個簡單的類:
data class NameTuple(@ColumnInfo(name = "first_name") val firstName: String?,@ColumnInfo(name = "last_name") val lastName: String?
)
  • 定義DAO函數:
@Query("SELECT first_name, last_name FROM user")
fun loadFullName(): List<NameTuple>
簡單參數傳遞

傳參的目的為了過濾操作。例如,以下代碼定義了一個返回超過特定年齡的所有用戶的方法:

@Query("SELECT * FROM user WHERE age > :minAge")
fun loadAllUsersOlderThan(minAge: Int): Array<User>@Query("SELECT * FROM user WHERE age BETWEEN :minAge AND :maxAge")
fun loadAllUsersBetweenAges(minAge: Int, maxAge: Int): Array<User>@Query("SELECT * FROM user WHERE first_name LIKE :search " +"OR last_name LIKE :search")
fun findUserWithName(search: String): List<User>
將一組參數傳遞
@Query("SELECT * FROM user WHERE region IN (:regions)")
fun loadUsersFromRegions(regions: List<String>): List<User>
3.5 返回Cursor
@Dao
interface UserDao {@Query("SELECT * FROM user WHERE age > :minAge LIMIT 5")fun loadRawUsersOlderThan(minAge: Int): Cursor
}

不推薦,因為它無法保證行是否存在或行包含哪些值。

四、定義對象之間的關系

4.1 兩張表之間的混合查詢

在 Room 中,您可以通過兩種方式定義和查詢實體之間的關系:

  • 使用具有嵌入式對象的中間數據類。

  • 使用具有多重映射返回值類型的關系型查詢方法。

中間數據類

在中間數據類方法中,您可以定義數據類,以便在 Room 實體之間建立關系。此數據類保存一個實體的實例與另一個實體的實例之間的配對(作為嵌入式對象)。然后,查詢方法可以返回此數據類的實例,以供您的應用使用。

例如,您可以定義 UserBook 數據類來表示已借閱特定圖書的圖書館用戶,并定義一個查詢方法用于從數據庫中檢索 UserBook 實例的列表:

@Dao
interface UserBookDao {@Query("SELECT user.name AS userName, book.name AS bookName " +"FROM user, book " +"WHERE user.id = book.user_id")fun loadUserAndBookNames(): LiveData<List<UserBook>>
}data class UserBook(val userName: String?, val bookName: String?)
返回Map(推薦)

room2.4支持如下操作:

@Query("SELECT * FROM user" +"JOIN book ON user.id = book.user_id"
)
fun loadUserAndBookNames(): Map<User, List<Book>>
4.2 創建嵌套對象(@Embeded)

有時,您可能希望在數據庫邏輯中將某個實體或數據對象表示為一個緊密的整體,即使該對象包含多個字段也是如此。在這些情況下,您可以使用 @Embedded 注釋表示要分解為表格中的子字段的對象。然后,您可以像查詢其他各個列一樣查詢嵌套字段。

例如,您的 User 類可以包含一個 Address 類型的字段,它表示名為 streetcitystatepostCode 的字段的組合。若要在表中單獨存儲組合列,請在帶有 @Embedded 注解的 User 類中添加 Address 字段,如以下代碼段所示:

data class Address(val street: String?,val state: String?,val city: String?,@ColumnInfo(name = "post_code") val postCode: Int
)@Entity
data class User(@PrimaryKey val id: Int,val firstName: String?,@Embedded val address: Address?
)

然后,表示 User 對象的表將包含具有以下名稱的列:idfirstNamestreetstatecitypost_code

七、更高級的用法

暫時不去學習,備查。查看官網。

2.5 表搜索支持
2.6 autoValue,java不可變值類
3.3 查詢多張表

您的部分查詢可能需要訪問多個表格才能計算出結果。您可以在 SQL 查詢中使用 JOIN 子句來引用多個表。

以下代碼定義了一種方法將三個表進行聯接,以便返回當前已出借給特定用戶的圖書:

@Query("SELECT * FROM book " +"INNER JOIN loan ON loan.book_id = book.id " +"INNER JOIN user ON user.id = loan.user_id " +"WHERE user.name LIKE :userName"
)
fun findBooksBorrowedByNameSync(userName: String): List<Book>
進階

此外,您還可以定義簡單對象以從多個聯接表返回若干列的子集,如【返回表中多列的子集】部分所述。以下代碼定義了一個 DAO,其中包含一個返回用戶姓名和所借閱圖書名稱的方法:

interface UserBookDao {@Query("SELECT user.name AS userName, book.name AS bookName " +"FROM user, book " +"WHERE user.id = book.user_id")fun loadUserAndBookNames(): LiveData<List<UserBook>>// You can also define this class in a separate file.data class UserBook(val userName: String?, val bookName: String?)
}
進階2-返回Map
//您可以直接從您的查詢方法返回 `User` 和 `Book` 的映射,而不是返回保存有 `User` 和 `Book` 實例配對的自定義數據類的實例列表。
@Query("SELECT * FROM user" +"JOIN book ON user.id = book.user_id"
)
fun loadUserAndBookNames(): Map<User, List<Book>>//GROUP BY以便利用 SQL 的功能進行高級計算和過濾。
@Query("SELECT * FROM user" +"JOIN book ON user.id = book.user_id" +"GROUP BY user.name WHERE COUNT(book.id) >= 3"
)
fun loadUserAndBookNames(): Map<User, List<Book>>//如果您不需要映射整個對象,還可以通過在查詢方法的 @MapInfo 注解中設置 keyColumn 和 valueColumn 屬性,返回查詢中特定列之間的映射:
@MapInfo(keyColumn = "userName", valueColumn = "bookName")
@Query("SELECT user.name AS username, book.name AS bookname FROM user" +"JOIN book ON user.id = book.user_id"
)
fun loadUserAndBookNames(): Map<String, List<String>>
3.4 Paging結合使用

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/90194.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/90194.shtml
英文地址,請注明出處:http://en.pswp.cn/web/90194.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

DOM編程全解析:操作、事件與存儲實戰指南

引言&#xff1a;DOM——JavaScript與網頁交互的橋梁 DOM&#xff08;文檔對象模型&#xff09; 是JavaScript操作HTML/XML文檔的接口&#xff0c;它將網頁文檔抽象為一個樹形結構&#xff0c;允許開發者通過API動態修改文檔的內容、結構和樣式。無論是實現動態交互&#xff0…

Ansible命令

Ansible命令 ansible 常用命令 /usr/bin/ansible   #Ansibe AD-Hoc 臨時命令執行工具&#xff0c;常用于臨時命令的執行 /usr/bin/ansible-doc    #Ansible 模塊功能查看工具 /usr/bin/ansible-galaxy   #下載/上傳優秀代碼或Roles模塊 的官網平臺&#xff0c;基于網…

SY6974芯片添加enable充電控制節點

1. 需求描述項目背景&#xff1a;基于 Qualcomm MDM9x07 平臺的 4G MIFI 產品&#xff0c;使用 Silergy 公司的 SY6974 充電 IC需求內容&#xff1a; 在環境 /sys/class/power_supply/sy6794/enable 下增加一個 sysfs 節點&#xff0c;用于控制是否允許充電&#xff1a;cat /sy…

趣玩-Ollama-Llm-Chatrbot

軟件說明 這個軟件本人是從零開始實現的聊天機器人。基于Ollama&#xff08;PythonApi &#xff09; Pyside&#xff0c;實現了聊天機器的基本功能&#xff0c;還有一些個性化的功能比如模型管理&#xff0c;敏感詞過濾&#xff0c;個性化主題設置&#xff0c;頭像設置等功能。…

在mac 上zsh 如何安裝最新的 go 工具

文章目錄方法一&#xff1a;使用 Homebrew&#xff08;推薦&#xff09;方法二&#xff1a;從官網下載安裝包方法三&#xff1a;使用 g&#xff08;Go 版本管理器&#xff09;方法四&#xff1a;使用 gvm&#xff08;Go Version Manager&#xff09;驗證安裝和配置常用 Go 工具…

(十九)深入了解 AVFoundation-編輯:使用 AVMutableVideoComposition 實現視頻加水印與圖層合成(上)——理論篇

一、引言在短視頻、Vlog、剪輯工具日益流行的今天&#xff0c;給視頻添加 Logo、水印、時間戳或動態貼紙&#xff0c;已經成為非常常見的功能需求。這類效果看似簡單&#xff0c;其實背后都涉及到“圖層合成”的處理&#xff1a;如何將一個靜態或動態的圖層&#xff08;如文字、…

Android NDK與JNI深度解析

核心概念定義&#xff1a;NDK (Native Development Kit): 是什么&#xff1a; 一套由 Google 提供的工具集合。目的&#xff1a; 允許 Android 開發者使用 C 和 C 等原生&#xff08;Native&#xff09;語言來實現應用程序的部分功能。包含內容&#xff1a; 交叉編譯器&#xf…

Golang各版本特性

1. Go各版本特性 | FeelingLife 2. https://chatgpt.com/share/68808f58-ae5c-800a-8153-5358098f301b 3.https://tonybai.com/2024/11/14/go-map-use-swiss-table/

HTML 轉 Word API 接口

HTML 轉 Word API 接口 支持網頁轉 Word&#xff0c;高效轉換為 Word&#xff0c;提供永久鏈接。 1. 產品功能 超高性能轉換效率&#xff1b;支持將傳遞的 HTML 轉換為 Word&#xff0c;支持 HTML 中的 CSS 格式在 Word 文檔中的呈現&#xff1b;支持傳遞網站的 URL&#xff…

Lucid Search: 極簡、隱私友好的問答式搜索引擎技術解析

Lucid Search: 極簡、隱私友好的問答式搜索引擎技術解析 產品定位與價值主張 Lucid Search 是一款革命性的問答式搜索引擎&#xff0c;其核心價值在于&#xff1a; 極簡體驗&#xff1a;無賬戶、無廣告、前端完全靜態隱私保護&#xff1a;不寫入 Cookie、不記錄 IP、無追蹤即…

卷積神經網絡:模型評估標準

一、分類模型評價指標在模型評估中&#xff0c;有多個標準用于衡量模型的性能&#xff0c;這些標準包括準確率&#xff08;Accuracy&#xff09;、精確率&#xff08;Precision&#xff09;、召回率&#xff08;Recall&#xff09;、F1 分數&#xff08;F1-Score&#xff09;等…

【前端工程化】前端開發中想做好發布管理可以從哪些方面著手?

在企業級后臺系統中&#xff0c;發布管理是整個開發流程的最終環節&#xff0c;也是最為關鍵的一環。它不僅涉及代碼構建完成后的部署操作&#xff0c;還包括版本控制、灰度發布、回滾機制等保障系統穩定性的措施。 本文主要圍繞發布流程設計、版本控制、部署方式、灰度策略和回…

替分布式=成本下降50% !

在數字化轉型的浪潮中&#xff0c;數據庫作為醫療信息系統的“心臟”&#xff0c;其穩定性與效率直接關乎醫療服務的質量。2024年10月30日&#xff0c;綿陽市第三人民醫院集成平臺的CDR數據庫成功從分布式數據庫Citus切換為國產集中式數據庫KingbaseES&#xff0c;并穩定運行至…

【Linux系統編程】基礎指令

基礎指令1. adduser指令&&passwd指令2. userdel指令3. pwd指令4. ls指令5. cd指令6. tree指令7. touch指令8. mkdir指令9. rmdir指令&&rm指令10. man指令11. cp指令12. mv指令13. cat指令14. more指令15. less指令16. head指令17. tail指令18. date指令19. cal…

區塊鏈之以太坊Hardhat開發框架——部署在windows為例

Hardhat 提供了一個靈活且易于使用的開發環境&#xff0c;可以輕松地編寫、測試和部署智能合約。Hardhat還內置了Hardhat 網絡&#xff08;Hardhat Node&#xff09;&#xff0c;它是為開發而設計的本地以太坊網絡。 下面是hardhat的官方文檔 https://hardhat.org/hardhat-ru…

Ubuntu 1804 編譯ffmpeg qsv MediaSDK libva 遇到的問題記錄

之前都是 用的xeon服務器的cpu 不支持intel QSV 硬件加速 最近把自己的 14年買的pc機裝上了ubuntu 1804 然后準備開啟ffmpeg qsv 硬件加速功能 CPU i3-4170 內存DDR3 16G 硬盤機械盤500G 主板ASUS B85M-G首先安裝vainfo工具apt install vainfo裝完提示如下出錯了 網上說是…

Elasticsearch(ES)介紹和安裝

目錄 一、Elasticsearch(ES)介紹 1.為什么需要單獨的搜索服務 2.全文檢索 3.Elasticsearch簡介 1.Elasticsearch的特點 2.應用場景 3.ElasticSearch數據的存儲和搜索原理 二、Elasticsearch(ES)安裝 1、拉取鏡像 2、創建目錄并給目錄賦權 3、創建并編輯配置文件 4、…

html結構解析

<!DOCTYPE html>&#xff1a;聲明為 HTML5 文檔 <html lang"zh-CN">&#xff1a;根元素&#xff0c;指定頁面語言為中文 <meta charset"UTF-8">&#xff1a;設置字符編碼&#xff0c;確保中文正常顯示 <meta name"viewport"…

面試150 最大子數組和

思路 貪心法&#xff1a;設定最小標志result為float(‘-inf’),遍歷一次數組元素進行求和&#xff0c;如果當前元素大于result&#xff0c;則更新result的值&#xff0c;如果sum小于0&#xff0c;則重新置0進行計算&#xff0c;最后返回result class Solution:def maxSubArray(…

MyBatis動態SQL實戰:告別硬編碼,擁抱智能SQL生成

MyBatis動態SQL實戰&#xff1a;告別硬編碼&#xff0c;擁抱智能SQL生成在電商平臺的用戶管理模塊中&#xff0c;需要面對多種不同的用戶查詢組合條件。當使用傳統的硬編碼SQL方式時&#xff0c;代碼膨脹到了2000多行&#xff0c;維護成本極高。而引入MyBatis動態SQL后&#xf…