Room数据库 vs SQLite:用过一次你就知道差距有多大!

打印 上一主题 下一主题

主题 1843|帖子 1843|积分 5529

Room是Jetpack提供的一个SQLite 的抽象层,它简化了对SQLite 数据库的操作。Room通过注解、编译时验证和清楚的 API,将数据库操作变得更加高效和安全,同时提供了与 Kotlin 协程、LiveData 和 RxJava 等库的集成支持。
在 Android 项目中使用 Room 数据库(Kotlin 示例)
以下示例展示了如安在 Android 项目中使用 Room 数据库,包括数据模子、DAO(数据访问对象)、数据库类以及如何进行增删改查操作。


1. 添加 Room 依赖

在 build.gradle 中添加 Room 依赖:
  1. dependencies {
  2.     def room_version = "2.5.2"  // 使用最新版本
  3.     implementation "androidx.room:room-runtime:$room_version"
  4.     annotationProcessor "androidx.room:room-compiler:$room_version" // Java 项目
  5.     kapt "androidx.room:room-compiler:$room_version"                // Kotlin 项目
  6.     // 可选:支持协程
  7.     implementation "androidx.room:room-ktx:$room_version"
  8.     // 可选:RxJava 支持
  9.     implementation "androidx.room:room-rxjava2:$room_version"
  10. }
复制代码

2. 创建数据实体

使用 @Entity 注解定义数据表。每个字段对应数据库表的一列。
User 数据类:
  1. import androidx.room.Entity
  2. import androidx.room.PrimaryKey
  3. @Entity(tableName = "users")
  4. data class User(
  5.     @PrimaryKey(autoGenerate = true) val id: Int = 0,
  6.     val name: String,
  7.     val age: Int,
  8.     val email: String
  9. )
复制代码


  • @Entity:定义一个表,tableName 指定表名。
  • @PrimaryKey(autoGenerate = true):指定主键并自动天生。

3. 创建 DAO(数据访问对象)

@Dao 注解用于定义数据库操作(增、删、改、查)。
UserDao 接口:
  1. import androidx.room.*
  2. @Dao
  3. interface UserDao {
  4.     @Insert
  5.     suspend fun insertUser(user: User)
  6.     @Insert
  7.     suspend fun insertAll(users: List<User>)
  8.     @Update
  9.     suspend fun updateUser(user: User)
  10.     @Delete
  11.     suspend fun deleteUser(user: User)
  12.     @Query("SELECT * FROM users")
  13.     fun getAllUsers(): List<User>
  14.     @Query("SELECT * FROM users WHERE id = :userId")
  15.     suspend fun getUserById(userId: Int): User?
  16.     @Query("DELETE FROM users")
  17.     suspend fun deleteAllUsers()
  18. }
复制代码


  • @Insert:用于插入数据。
  • @Update:更新数据。
  • @Delete:删除数据。
  • @Query:自定义查询 SQL 语句。

4. 定义数据库类

使用 @Database 注解定义数据库类,继承 RoomDatabase。
AppDatabase 类:
  1. import androidx.room.Database
  2. import androidx.room.RoomDatabase
  3. @Database(entities = [User::class], version = 1)
  4. abstract class AppDatabase : RoomDatabase() {
  5.     abstract fun userDao(): UserDao
  6. }
复制代码


  • entities:指定所有的数据表。
  • version:数据库版本号,用于迁移操作。
  • abstract fun userDao():定义 DAO 的访问方法。

5. 初始化数据库

在应用中初始化 Room 数据库,可以使用 Room.databaseBuilder。
MyApp 类:
  1. import android.app.Application
  2. import androidx.room.Room
  3. class MyApp : Application() {
  4.     companion object {
  5.         lateinit var database: AppDatabase
  6.     }
  7.     override fun onCreate() {
  8.         super.onCreate()
  9.         database = Room.databaseBuilder(
  10.             applicationContext,
  11.             AppDatabase::class.java,
  12.             "my_database"
  13.         ).build()
  14.     }
  15. }
复制代码


  • 使用 Room.databaseBuilder 创建数据库实例。
  • 设置数据库名称 "my_database"。
  • 在 Application 类中初始化,确保全局可访问。

6. 使用 Room 数据库

在 Activity 或 ViewModel 中使用 UserDao 操作数据库。
示例:ViewModel 类
  1. import androidx.lifecycle.ViewModel
  2. import androidx.lifecycle.viewModelScope
  3. import kotlinx.coroutines.launch
  4. class UserViewModel : ViewModel() {
  5.     private val userDao = MyApp.database.userDao()
  6.     // 插入数据
  7.     fun addUser(user: User) {
  8.         viewModelScope.launch {
  9.             userDao.insertUser(user)
  10.         }
  11.     }
  12.     // 获取所有用户数据
  13.     fun getAllUsers(): List<User> {
  14.         return userDao.getAllUsers()
  15.     }
  16.     // 根据 ID 查询用户
  17.     fun getUserById(userId: Int) {
  18.         viewModelScope.launch {
  19.             val user = userDao.getUserById(userId)
  20.             println("User: $user")
  21.         }
  22.     }
  23.     // 删除所有用户
  24.     fun clearUsers() {
  25.         viewModelScope.launch {
  26.             userDao.deleteAllUsers()
  27.         }
  28.     }
  29. }
复制代码

7. 在 Activity 中使用 ViewModel

在 Activity 中调用 ViewModel 进行数据库操作。
示例:MainActivity
  1. import android.os.Bundle
  2. import androidx.activity.viewModels
  3. import androidx.appcompat.app.AppCompatActivity
  4. class MainActivity : AppCompatActivity() {
  5.     private val userViewModel: UserViewModel by viewModels()
  6.     override fun onCreate(savedInstanceState: Bundle?) {
  7.         super.onCreate(savedInstanceState)
  8.         setContentView(R.layout.activity_main)
  9.         // 插入用户
  10.         userViewModel.addUser(User(name = "John", age = 30, email = "john@example.com"))
  11.         // 获取所有用户
  12.         val users = userViewModel.getAllUsers()
  13.         println("All Users: $users")
  14.         // 删除所有用户
  15.         userViewModel.clearUsers()
  16.     }
  17. }
复制代码

8. 运行效果



  • 添加新用户到数据库。
  • 查询所有用户并输出到日记。
  • 删除所有用户数据。

为什么要用 Room而不是直接使用SQLite?
固然SQLite 是 Android 平台原生的数据库,但使用SQLite 直接操作数据库存在诸多问题,Room正是为了解决这些问题而筹划的。
一、 SQL 查询容易堕落,缺乏编译时验证
SQLite 问题:在SQLite 中,SQL 语句是字符串形式写在代码中的,只有运行时才会检查是否堕落。如果拼写错误、表名/列名错误,问题只能在运行时发现,增加了调试难度。
Room解决:Room在编译时会验证 SQL 语句的正确性。如果 SQL 语句有问题,编译会直接报错,克制运行时错误。
示例:
  1.    @Query("SELECT * FROM user")  // Room会检查 user 表是否存在
  2.    fun getAllUsers(): List<User>
复制代码
二、手写代码繁琐且易堕落
SQLite 问题:使用SQLite,开发者必要手动编写表的创建、升级语句,以及繁琐的 CRUD 操作代码。
Room解决:Room提供了简洁的注解来简化这些操作,好比 @Entity、@Dao、@Insert、@Update 和 @Delete。
示例:
  1.    @Dao
  2.    interface UserDao {
  3.        @Insert
  4.        suspend fun insert(user: User)
  5.        @Query("SELECT * FROM users WHERE age > :minAge")
  6.        fun getUsersAboveAge(minAge: Int): List<User>
  7.    }
复制代码
开发者只需通过注解标记方法,Room会自动天生底层的 SQL 操作代码,无需手动编写。
三、 缺乏生命周期感知,容易引发内存走漏
SQLite 问题:直接使用SQLite 与 UI 组件交互时,容易引起内存走漏或线程安全问题。
Room解决:Room可以与 LiveData 或 Flow 结合使用,实现对数据的观察和 UI 的自动更新,同时与生命周期感知组件绑定,克制内存走漏。
示例:结合 LiveData 使用
  1.    @Dao
  2.    interface UserDao {
  3.        @Query("SELECT * FROM users")
  4.        fun getAllUsers(): LiveData<List<User>>
  5.    }
  6.    // 在 Activity 或 Fragment 中观察数据
  7.    userDao.getAllUsers().observe(this, Observer { users ->
  8.        // 更新 UI
  9.    })
复制代码
四、无法支持 Kotlin 协程或 RxJava 的异步操作
SQLite 问题:SQLite 原生 API 不支持 Kotlin 协程或 RxJava,进行异步操作必要大量手动代码编写。
Room解决:Room提供了对 Kotlin 协程 和 RxJava 的内置支持,使得数据库操作更加当代化、异步化。
示例:协程支持
  1.    @Insert
  2.    suspend fun insert(user: User)
复制代码
示例:RxJava 支持
  1.    @Query("SELECT * FROM users")
  2.    fun getAllUsers(): Flowable<List<User>>
复制代码
五、数据迁移复杂,版本管理困难
SQLite 问题:数据库版本更新时,必要手动编写复杂的 SQL 迁移代码,容易堕落。
Room解决:Room提供了自动迁移和 @AutoMigration 功能,简化了数据库版本升级过程。
示例:自动迁移
  1.    @Database(entities = [User::class], version = 2, autoMigrations = [AutoMigration(from = 1, to = 2)])
  2.    abstract class AppDatabase : RoomDatabase() {
  3.        abstract fun userDao(): UserDao
  4.    }
复制代码

六、性能问题
SQLite 问题:开发者可能会忽略性能优化,好比使用事务、批量操作等,导致数据库性能低下。
Room解决:Room提供了 事务支持 和 批量插入操作,自动优化性能。
示例:事务支持
  1.    @Transaction
  2.    suspend fun insertAndUpdate(user: User) {
  3.        insert(user)
  4.        update(user)
  5.    }
复制代码
总结


  • 数据模子:@Entity 定义数据库表。
  • 数据操作:@Dao 提供增删改查方法。
  • 数据库定义:RoomDatabase 负责连接数据库。
  • 协程支持:通过 suspend 关键字实现异步数据库操作。
  • 生命周期集成:结合 ViewModel 管理数据库操作,确保线程安全。
通过 Room,可以轻松、高效地管理数据库,克制了手动编写 SQL 和处理惩罚 SQLite 的复杂操作。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

没腿的鸟

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表