当前位置: 首页 > article >正文

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 等注解定义表结构和字段。
    @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 等注解定义数据库操作方法。
    @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 类,并指定实体类和版本号。
    @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 等属性定义表的主键、外键和索引。
    @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 等注解定义数据库操作方法。
    @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 数据库。
    • 需要指定实体类和版本号。
    @Database(entities = [User::class], version = 1)
    abstract class AppDatabase : RoomDatabase() {
        abstract fun userDao(): UserDao
    }
    
  • @ColumnInfo:

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

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

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

15.4 Room 常用操作

  • 插入数据:

    @Insert
    suspend fun insertUser(user: User)
    
  • 查询数据:

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

    @Update
    suspend fun updateUser(user: User)
    
  • 删除数据:

    @Delete
    suspend fun deleteUser(user: User)
    
  • 事务操作:

    @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 集成:

    @Query("SELECT * FROM users")
    fun getAllUsers(): LiveData<List<User>>
    
    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 集成:

    @Query("SELECT * FROM users")
    fun getAllUsers(): Flow<List<User>>
    
    @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 进行数据持久化操作,实现应用数据的存储和查询。


http://www.kler.cn/a/402510.html

相关文章:

  • [极客大挑战 2019]BabySQL--详细解析
  • 生成对抗网络模拟缺失数据,辅助PAMAP2数据集仿真实验
  • 【Isaac Sim】相关问题汇总
  • leetcode 50个简单和中等难度的题
  • 海洋通信船舶组网工业4G路由器应用
  • java实现小程序接口返回Base64图片
  • Spark Catalyst 优化器具有高度的可扩展性,如何自定义优化规则?
  • Zero-Shot Next-Item Recommendation using Large Pretrained Language Models-问题咨询
  • 阿里云 DevOps 资源安全扫描实践
  • nginx配置不缓存资源
  • Spark SQL大数据分析快速上手-完全分布模式安装
  • LLM( Large Language Models)典型应用介绍 1 -ChatGPT Large language models
  • 3_Flink CDC
  • Eagle-OJ 开源的在线编程训练平台
  • Mybatis框架之适配器模式 (Adapter Pattern)
  • ReactPress:基于pnpm的Mono Repository方案介绍
  • Docker用法详解
  • Docker-Compose 快速部署安装 Nginx 或其他应用
  • uniapp页面样式和布局和nvue教程详解
  • 2020 年 9 月青少年软编等考 C 语言三级真题解析
  • Django实现智能问答助手-进一步完善
  • Go(java基础)
  • AI 赋能电商的未来:购物推荐、会员分类与智能定价的创新实践
  • 2. SpringBoot + MQTT 门禁设备对接实战
  • Kafka Stream实战教程
  • 深入解析小程序组件:view 和 scroll-view 的基本用法