一、對象關(guān)系映射 - ORM / Object Relational Mapping
Android 系統(tǒng)中使用的數(shù)據(jù)庫是 SQLite 關(guān)系型數(shù)據(jù)庫 , 使用 Android 提供的 api 訪問 SQLite 數(shù)據(jù)庫非常繁瑣 , 由此出現(xiàn)了很多 ORM 框架 ;
ORM 英文全稱 Object Relational Mapping , 對象關(guān)系映射 ;
對象關(guān)系映射 ORM 是一種編程技術(shù) , 面向?qū)ο缶幊陶Z言 與 關(guān)系型數(shù)據(jù)庫 之間的 映射 ;
- 對象 指的是 面向?qū)ο缶幊陶Z言 ,
- 關(guān)系 指的是 關(guān)系型數(shù)據(jù)庫 ;
借助 ORM 對象關(guān)系映射 框架 訪問數(shù)據(jù)庫 , 可以 簡化數(shù)據(jù)庫操作流程 , 開發(fā)人員使用面向?qū)ο?API 與 數(shù)據(jù)庫進(jìn)行交互 , 比編寫復(fù)雜的 SQL 語句操作數(shù)據(jù)庫 要簡單很多 ;
ORM 框架常使用 元數(shù)據(jù) 將 數(shù)據(jù)庫表 與 編程語言中的類 進(jìn)行映射 , 數(shù)據(jù)庫表字段 與 類中的字段 一一對應(yīng) , 常用的元數(shù)據(jù)有 :
- 注解
- 配置文件
ORM 框架優(yōu)點(diǎn) :
- 提高了開發(fā)效率 : 使用 ORM 操作數(shù)據(jù)庫 簡化了數(shù)據(jù)庫操作過程 , 令代碼更容易開發(fā)維護(hù) ;
- 提高了可移植性 : 使用 ORM 框架操作數(shù)據(jù)庫 , 可以在 不改變代碼的前提下 , 更換底層數(shù)據(jù)庫 ;
- 提高了性能 : 可以 總體優(yōu)化 ORM 框架的 增刪查改 操作性能 ;
- 提高了安全性 : 可避免直接使用 SQL 語句查詢時(shí) , 產(chǎn)生的 SQL 注入攻擊 ;
常見的 ORM 框架 :
- Android 平臺 : GreenDao / ORMLite ;
- JavaEE 平臺 : Hibernate ;
- .NET 平臺 : Entity Framework ;
- Python 平臺 : DiangoORM ;
在 Android 中 , Google 官方提供了一個(gè)基于 SQLite 關(guān)系型數(shù)據(jù)庫操作封裝的 ORM 框架 , Room 框架 ;
二、Room 框架的組成部分
1、@Entity / @Dao / @Database 注解
Room 框架中的重要注解 :
@Entity 注解 : 用于修飾 JavaBean 實(shí)體類 , 對應(yīng)數(shù)據(jù)庫中的一張表結(jié)構(gòu) ;
@Dao 注解 : 用于修飾 數(shù)據(jù)庫訪問對象 類 , 其中定義了 數(shù)據(jù)庫的 增刪改查 函數(shù) ;
-
@Database 注解 :
修飾 數(shù)據(jù)庫持有者 , 數(shù)據(jù)庫持有者 就是 數(shù)據(jù)庫鏈接對象 , 是 應(yīng)用持久化數(shù)據(jù)底層連接的接入點(diǎn) ;
- 使用 @Database 注解 修飾的類 , 該類必須繼承 RoomDatabase 抽象類 ;
- 在該注解中 , 需要定義 數(shù)據(jù)庫 相關(guān)的 實(shí)體類 列表 ;
- 數(shù)據(jù)庫持有者 包含 沒有參數(shù)的抽象方法 , 該方法返回 Dao 對象 ;
2、Entity 實(shí)體類 / Dao 數(shù)據(jù)庫訪問對象 / Database 數(shù)據(jù)庫持有者 之間的關(guān)系
Database 數(shù)據(jù)庫持有者 , Dao ( Data Access Objects ) 數(shù)據(jù)庫訪問對象 , Entity 實(shí)體類 , 三者之間的關(guān)系如下 :
- 首先 , 在 Android 應(yīng)用中 , 通過 Room 框架的 Database 拿到 數(shù)據(jù)庫持有者 對象 ;
- 然后 , 通過 數(shù)據(jù)庫持有者 Database 拿到 Dao ( Data Access Objects ) 數(shù)據(jù)庫訪問對象 ;
- 最后 , 通過 Dao ( Data Access Objects ) 數(shù)據(jù)庫訪問對象 訪問 數(shù)據(jù)庫中每個(gè)表對應(yīng)的 Entity 實(shí)體類對象 ;

三、Room 框架使用步驟
Room 框架使用步驟 :
- 添加 Room 框架依賴
- 創(chuàng)建 Entity 實(shí)體類
- 創(chuàng)建 Dao 實(shí)體類
- 創(chuàng)建 RoomDatabase 數(shù)據(jù)庫實(shí)例對象
- 初始化 Room 數(shù)據(jù)庫
- 調(diào)用 Dao 執(zhí)行數(shù)據(jù)庫增刪改查操作
1、添加 Room 框架依賴
在 Module 模塊下的 build.gradle 構(gòu)建腳本 中 , 配置如下依賴項(xiàng) :
dependencies {
// 配置 Room 框架版本號
def room_version = "2.4.0"
// 核心運(yùn)行時(shí)依賴庫 在應(yīng)用運(yùn)行時(shí)提供 Room 框架的數(shù)據(jù)庫相關(guān)核心功能
implementation "androidx.room:room-runtime:$room_version"
// 編譯時(shí)依賴項(xiàng) 在編譯時(shí)實(shí)時(shí)生成 Room 代碼 如 : Dao 實(shí)現(xiàn)類 / AppDatabase 子類 / Entity 實(shí)體類映射器
annotationProcessor "androidx.room:room-compiler:$room_version"
// 可選配置項(xiàng) - 支持 Kotlin 擴(kuò)展和協(xié)程的 Room 框架 如果使用的是 Kotlin 語言必須導(dǎo)入該依賴
implementation "androidx.room:room-ktx:$room_version"
}
androidx.room:room-runtime 依賴庫 是 運(yùn)行時(shí)核心依賴庫 , 在應(yīng)用運(yùn)行時(shí)提供 Room 框架的數(shù)據(jù)庫相關(guān)核心功能 ; 該依賴庫 包含了 Room 持久化庫的核心功能 , 如 :
- RoomDatabase 類:用于表示數(shù)據(jù)庫,可以包含一個(gè)或多個(gè)表,并提供了一些方法來操作數(shù)據(jù)庫,例如插入、刪除和查詢數(shù)據(jù)等。
- Entity 注解:用于標(biāo)記實(shí)體類,指定實(shí)體類對應(yīng)的數(shù)據(jù)庫表的名稱和字段信息等。
- Dao 數(shù)據(jù)庫訪問對象:用于定義訪問數(shù)據(jù)庫的方法,例如查詢、插入和刪除等操作。
- Query 注解:用于標(biāo)記 DAO 接口中的方法,并指定 SQL 查詢語句。
- PrimaryKey 注解:用于指定實(shí)體類中的主鍵字段。
- TypeConverters 注解:用于標(biāo)記類型轉(zhuǎn)換器類,將特定類型的數(shù)據(jù)轉(zhuǎn)換為數(shù)據(jù)庫中的原生類型。
androidx.room:room-compiler 依賴庫 是 Room 持久化庫中的一個(gè) 編譯時(shí)依賴項(xiàng) , 用于 在編譯時(shí)生成 Room 的如下實(shí)現(xiàn)代碼 :
- AppDatabase 的子類 , 用于創(chuàng)建和訪問數(shù)據(jù)庫 ;
- Dao 數(shù)據(jù)庫訪問對象實(shí)現(xiàn)類 , 用于執(zhí)行 SQL 查詢和操作 ;
- 實(shí)體類 Entity 的映射器 , 用于將數(shù)據(jù)庫中的數(shù)據(jù)映射到實(shí)體類中 ;
androidx.room:room-ktx 依賴庫 , 提供了 Kotlin 擴(kuò)展功能 , 如果使用的是 Kotlin 語言 , 則必須導(dǎo)入該依賴庫 ;
2、創(chuàng)建 Entity 實(shí)體類
創(chuàng)建 Entity 實(shí)體類 , 該實(shí)體類對應(yīng)著數(shù)據(jù)庫中的一張表 , 需要使用如下注解修飾
- 使用 @Entity 注解修飾實(shí)體類 , 并指定 數(shù)據(jù)庫表名 ;
- 使用 @PrimaryKey 注解修飾主鍵值 ,
- 使用 @ColumnInfo 注解修飾 數(shù)據(jù)庫表 列名 對應(yīng)的字段 ;
@Entity(tableName = "users")
data class User(
@PrimaryKey val id: Int,
@ColumnInfo(name = "name") val name: String,
@ColumnInfo(name = "age") val age: Int
)
3、創(chuàng)建 Dao 實(shí)體類
創(chuàng)建 Dao 實(shí)體類 : 創(chuàng)建用于訪問數(shù)據(jù)庫的 DAO 接口 , 并使用注解指定 SQL 查詢語句等信息 ;
- 使用 @Dao 注解修飾整個(gè) Dao 實(shí)體類 ;
- 使用 @Query 注解修飾查詢函數(shù) ;
- 使用 @Insert 注解修飾插入函數(shù) ;
- 使用 @Delete 注解修飾刪除函數(shù) ;
@Dao
interface UserDao {
@Query("SELECT * FROM users")
fun getAll(): List<User>
@Insert
fun insert(user: User)
@Delete
fun delete(user: User)
}
4、創(chuàng)建 RoomDatabase 數(shù)據(jù)庫實(shí)例對象
創(chuàng)建 RoomDatabase 數(shù)據(jù)庫實(shí)例對象 : 創(chuàng)建 RoomDatabase 的子類實(shí)例對象 , 并定義抽象方法以獲取 DAO 實(shí)例 ;
@Database(entities = arrayOf(User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
5、初始化 Room 數(shù)據(jù)庫
初始化數(shù)據(jù)庫 : 在應(yīng)用程序中使用 Room 數(shù)據(jù)庫之前 , 必須先創(chuàng)建數(shù)據(jù)庫實(shí)例 ;
val db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java, "database-name"
).build()
6、調(diào)用 Dao 執(zhí)行數(shù)據(jù)庫增刪改查操作
調(diào)用 Dao 執(zhí)行數(shù)據(jù)庫增刪改查操作 :
db.userDao().insert(User(1, "John", 25))
val users = db.userDao().getAll()