Android Jetpack組件化之ORM 數(shù)據(jù)庫訪問框架詳解

一、對象關(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í)體類對象 ;
image.png

三、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()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容