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 进行数据持久化操作,实现应用数据的存储和查询。

相关推荐
xvch2 小时前
Kotlin 2.1.0 入门教程(二十五)类型擦除
android·kotlin
夜泉_ly2 小时前
MySQL -安装与初识
数据库·mysql
qq_529835353 小时前
对计算机中缓存的理解和使用Redis作为缓存
数据库·redis·缓存
月光水岸New5 小时前
Ubuntu 中建的mysql数据库使用Navicat for MySQL连接不上
数据库·mysql·ubuntu
狄加山6755 小时前
数据库基础1
数据库
我爱松子鱼6 小时前
mysql之规则优化器RBO
数据库·mysql
chengooooooo6 小时前
苍穹外卖day8 地址上传 用户下单 订单支付
java·服务器·数据库
李长渊哦6 小时前
常用的 JVM 参数:配置与优化指南
java·jvm
Rverdoser7 小时前
【SQL】多表查询案例
数据库·sql
Galeoto7 小时前
how to export a table in sqlite, and import into another
数据库·sqlite