Android开发实战班 - 数据持久化 - Room 数据库应用

在 Android 应用开发中,数据持久化是实现用户数据保存、应用状态保存等功能的重要手段。Room 是 Google 推出的一个基于 SQLite 的持久化库,提供了更简洁、安全和强大的数据库操作接口。Room 抽象了 SQLite 数据库的使用,简化了数据库操作,并提供了编译时 SQL 语句检查等功能。本章节将介绍 Room 数据库的基本概念、架构、常用注解以及在 Android 项目中的应用,帮助学员掌握 Room 数据库的使用。

15.1 Room 简介

  • Room 的历史与发展:

    • Room 是 Google 在 2017 年推出的持久化库,旨在简化 Android 应用中的 SQLite 数据库操作。
    • Room 提供了更简洁的 API,编译时 SQL 语句检查,以及与 LiveData 和 Flow 的无缝集成。
  • Room 的优势:

    • 简洁易用: 相比直接使用 SQLite,Room 提供了更简洁的 API,简化了数据库操作。
    • 编译时检查: Room 在编译时会检查 SQL 语句的正确性,避免运行时错误。
    • 与 LiveData 和 Flow 集成: Room 支持与 LiveData 和 Flow 集成,可以方便地观察数据库数据的变化。
    • 支持注解: Room 使用注解来定义实体、DAO 和数据库,代码更简洁易读。
    • 线程安全: Room 默认在后台线程中执行数据库操作,避免阻塞主线程。

15.2 Room 架构

Room 主要由三个组件组成:

  1. Entity(实体):

    • 实体类表示数据库中的表。
    • 使用 @Entity 注解定义实体类,并使用 @PrimaryKey, @ColumnInfo 等注解定义表结构和字段。
    kotlin 复制代码
    @Entity(tableName = "users")
    data class User(
        @PrimaryKey(autoGenerate = true) val id: Int,
        @ColumnInfo(name = "first_name") val firstName: String?,
        @ColumnInfo(name = "last_name") val lastName: String?
    )
  2. DAO(数据访问对象):

    • DAO 类用于定义数据库操作,例如查询、插入、更新、删除等。
    • 使用 @Dao 注解定义 DAO 接口,并使用 @Query, @Insert, @Update, @Delete 等注解定义数据库操作方法。
    kotlin 复制代码
    @Dao
    interface UserDao {
        @Query("SELECT * FROM users")
        fun getAllUsers(): LiveData<List<User>>
    
        @Query("SELECT * FROM users WHERE id = :id")
        fun getUserById(id: Int): User
    
        @Insert
        suspend fun insertUser(user: User)
    
        @Update
        suspend fun updateUser(user: User)
    
        @Delete
        suspend fun deleteUser(user: User)
    }
  3. Database(数据库):

    • Database 类是 Room 数据库的入口,用于获取 DAO 实例。
    • 使用 @Database 注解定义 Database 类,并指定实体类和版本号。
    kotlin 复制代码
    @Database(entities = [User::class], version = 1)
    abstract class AppDatabase : RoomDatabase() {
        abstract fun userDao(): UserDao
    
        companion object {
            @Volatile
            private var INSTANCE: AppDatabase? = null
    
            fun getDatabase(context: Context): AppDatabase {
                return INSTANCE ?: synchronized(this) {
                    val instance = Room.databaseBuilder(
                        context.applicationContext,
                        AppDatabase::class.java,
                        "app_database"
                    ).build()
                    INSTANCE = instance
                    instance
                }
            }
        }
    }

15.3 Room 常用注解

  • @Entity:

    • 定义实体类,表示数据库中的表。
    • 可以使用 tableName 属性指定表名。
    • 可以使用 primaryKeys, foreignKeys, indices 等属性定义表的主键、外键和索引。
    kotlin 复制代码
    @Entity(tableName = "users")
    data class User(
        @PrimaryKey(autoGenerate = true) val id: Int,
        @ColumnInfo(name = "first_name") val firstName: String?,
        @ColumnInfo(name = "last_name") val lastName: String?
    )
  • @Dao:

    • 定义 DAO 接口,用于定义数据库操作。
    • 可以使用 @Query, @Insert, @Update, @Delete 等注解定义数据库操作方法。
    kotlin 复制代码
    @Dao
    interface UserDao {
        @Query("SELECT * FROM users")
        fun getAllUsers(): LiveData<List<User>>
    
        @Insert
        suspend fun insertUser(user: User)
    
        @Update
        suspend fun updateUser(user: User)
    
        @Delete
        suspend fun deleteUser(user: User)
    }
  • @Database:

    • 定义 Database 类,表示 Room 数据库。
    • 需要指定实体类和版本号。
    kotlin 复制代码
    @Database(entities = [User::class], version = 1)
    abstract class AppDatabase : RoomDatabase() {
        abstract fun userDao(): UserDao
    }
  • @ColumnInfo:

    • 定义实体类字段对应的数据库列。
    • 可以使用 name 属性指定列名。
    kotlin 复制代码
    @ColumnInfo(name = "first_name")
    val firstName: String?
  • @PrimaryKey:

    • 定义实体类的主键。
    • 可以使用 autoGenerate 属性指定主键是否自动生成。
    kotlin 复制代码
    @PrimaryKey(autoGenerate = true)
    val id: Int
  • @Ignore:

    • 忽略实体类中的字段,不将其映射到数据库表中。
    kotlin 复制代码
    @Ignore
    val tempData: String?

15.4 Room 常用操作

  • 插入数据:

    kotlin 复制代码
    @Insert
    suspend fun insertUser(user: User)
  • 查询数据:

    kotlin 复制代码
    @Query("SELECT * FROM users")
    fun getAllUsers(): LiveData<List<User>>
    
    @Query("SELECT * FROM users WHERE id = :id")
    fun getUserById(id: Int): User
  • 更新数据:

    kotlin 复制代码
    @Update
    suspend fun updateUser(user: User)
  • 删除数据:

    kotlin 复制代码
    @Delete
    suspend fun deleteUser(user: User)
  • 事务操作:

    kotlin 复制代码
    @Transaction
    suspend fun insertOrUpdateUser(user: User) {
        val existingUser = getUserById(user.id)
        if (existingUser != null) {
            updateUser(user)
        } else {
            insertUser(user)
        }
    }

15.5 Room 与 LiveData 和 Flow

Room 支持与 LiveData 和 Flow 集成,可以方便地观察数据库数据的变化。

  • 与 LiveData 集成:

    kotlin 复制代码
    @Query("SELECT * FROM users")
    fun getAllUsers(): LiveData<List<User>>
    kotlin 复制代码
    class MyActivity : AppCompatActivity() {
        private lateinit var viewModel: MyViewModel
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
            viewModel.users.observe(this) { users ->
                // 更新 UI
            }
    
            viewModel.loadUsers()
        }
    }
  • 与 Flow 集成:

    kotlin 复制代码
    @Query("SELECT * FROM users")
    fun getAllUsers(): Flow<List<User>>
    kotlin 复制代码
    @Composable
    fun MyComposable(viewModel: MyViewModel) {
        val users by viewModel.users.collectAsState()
    
        LazyColumn {
            items(users) { user ->
                Text(text = user.firstName)
            }
        }
    }

15.6 实战案例

  1. 案例一:使用 Room 实现用户列表应用

    • 定义 User 实体类。
    • 定义 UserDao 接口,添加查询、插入、更新、删除方法。
    • 创建 AppDatabase 类,初始化 Room 数据库。
    • 创建 ViewModel,使用 Room 进行数据库操作。
    • 在 Activity 中观察 ViewModel 的 LiveData,更新 RecyclerView。
  2. 案例二:使用 Room 实现图片浏览应用

    • 定义 Image 实体类。
    • 定义 ImageDao 接口,添加查询、插入、更新、删除方法。
    • 创建 AppDatabase 类,初始化 Room 数据库。
    • 创建 ViewModel,使用 Room 进行数据库操作。
    • 在 Jetpack Compose Composable 中观察 ViewModel 的 Flow,更新 UI。

15.7 课后作业

  1. 任务一:使用 Room 实现用户列表应用

    • 定义 User 实体类。
    • 定义 UserDao 接口,添加查询、插入、更新、删除方法。
    • 创建 AppDatabase 类,初始化 Room 数据库。
    • 创建 ViewModel,使用 Room 进行数据库操作。
    • 在 Activity 中观察 ViewModel 的 LiveData,更新 RecyclerView。
  2. 任务二:使用 Room 实现图片浏览应用

    • 定义 Image 实体类。
    • 定义 ImageDao 接口,添加查询、插入、更新、删除方法.
    • 创建 AppDatabase 类,初始化 Room 数据库.
    • 创建 ViewModel,使用 Room 进行数据库操作.
    • 在 Jetpack Compose Composable 中观察 ViewModel 的 Flow,更新 UI.
  3. 任务三:使用 Room 实现网络请求缓存

    • 定义网络请求结果实体类.
    • 定义 DAO 接口,添加插入和查询方法.
    • 创建 ViewModel,使用 Room 进行数据库操作.
    • 在 Activity 中使用协程进行网络请求,并将结果保存到数据库.
    • 在 Activity 中观察 ViewModel 的 LiveData,更新 UI.

通过本章节的学习,学员将能够掌握 Room 数据库的基本概念、架构、常用注解以及在 Android 项目中的应用,并能够使用 Room 进行数据持久化操作,实现应用数据的存储和查询。

相关推荐
3***g2059 分钟前
redis连接服务
数据库·redis·bootstrap
深海呐12 分钟前
Android WebView吊起软键盘遮挡输入框的问题解决
android·webview·android 键盘遮挡·webview键盘遮挡
摘星编程14 分钟前
RAG的下一站:检索增强生成如何重塑企业知识中枢?
android·人工智能
m0_5981772317 分钟前
SQL 方法函数(1)
数据库
oMcLin18 分钟前
如何在Oracle Linux 8.4上通过配置Oracle RAC集群,确保企业级数据库的高可用性与负载均衡?
linux·数据库·oracle
信创天地18 分钟前
核心系统去 “O” 攻坚:信创数据库迁移的双轨运行与数据一致性保障方案
java·大数据·数据库·金融·架构·政务
fatiaozhang952721 分钟前
基于slimBOXtv 9.19 V2(通刷S905L3A/L3AB)ATV-安卓9-通刷-线刷固件包
android·电视盒子·刷机固件·机顶盒刷机·slimboxtv9.19v2·slimboxtv
胖咕噜的稞达鸭21 分钟前
进程间的通信(1)(理解管道特性,匿名命名管道,进程池,systeam V共享内存是什么及优势)重点理解代码!
linux·运维·服务器·数据库
德彪稳坐倒骑驴25 分钟前
Sqoop入门常用命令
数据库·hadoop·sqoop
资深web全栈开发25 分钟前
pg on delete 策略探讨
数据库·pg