美文网首页
Android中Room的使用

Android中Room的使用

作者: 小城哇哇 | 来源:发表于2023-06-13 21:15 被阅读0次

    Room 持久性库在 SQLite 上提供了一个抽象层,以便在充分利用 SQLite 的强大功能的同时,能够流畅地访问数据库。具体来说,Room 具有以下优势:

    • 针对 SQL 查询的编译时验证。
    • 可最大限度减少重复和容易出错的样板代码的方便注解。
    • 简化了数据库迁移路径。

    step1:app/build.gradle中引入room

    implementation "androidx.room:room-ktx:2.2.5" 
    kapt "androidx.room:room-compiler:2.2.5"
    
    

    step2:创建实体类

    这个类就是要存储的数据结构,通过@Entity(tableName="test_table")定义并指定表名。类中的每个属性代表表中的一。Room 最终会使用这些属性来创建表并将数据库行中的对象实例化

    //声明数据表,并且指定数据表名称
    @Entity(tableName = "test_table")
    data class TestEntity(@PrimaryKey(autoGenerate = true) val id: Int, @ColumnInfo(name = "name")val name:String)
    //如果列名也叫做word可以省略@ColumnInfo
    
    

    step3:创建DAO

    其实就是提供对数据表的增删改查。在 DAO(数据访问对象)中,您可以指定 SQL 查询并将其与方法调用相关联。编译器会检查 SQL 并根据常见查询的方便的注解(如 @Insert)生成查询。Room 会使用 DAO 为代码创建整洁的 API。DAO 必须是一个接口或抽象类。默认情况下,所有查询都必须在单独的线程上执行。Room 支持 Kotlin 协程,您可使用 suspend 修饰符对查询进行注解,然后从协程或其他挂起函数对其进行调用。

    @Dao
        interface TestDao {
        @Query("SELECT * FROM test_table ORDER BY word ASC")
        fun getSavedEntities(): Flow<List<TestEntity>>
    
        @Insert(onConflict = OnConflictStrategy.IGNORE)
        suspend fun insert(entity: TestEntity)
    
        @Query("DELETE FROM test_table")
        suspend fun deleteAll()
    }
    
    
    • TestDao 是一个接口,DAO 必须是接口或抽象类
    • @Dao 注解将其标识为 Room 的 DAO 类。
    • suspend fun insert(word: TestEntity):声明挂起函数以插入一个字词。
    • @Insert 注解是一种特殊的 DAO 方法注解,使用 DAO 方法注解时,您无需提供任何 SQL!(还有用于删除和更新行的 @Delete@Update注解)
    • onConflict = OnConflictStrategy.IGNORE:所选 onConflict 策略将忽略与列表中的现有字词完全相同的新字词。如需详细了解可用的冲突策略,请参阅相关文档
    • suspend fun deleteAll():声明挂起函数以删除所有字词。
    • 没有便于删除多个实体的注解,因此实体中要带有通用 @Query 注解。
    • @Query("DELETE FROM word_table"):@Query 要求您将 SQL 查询作为字符串参数提供给注解,以执行复杂的读取查询及其他操作。
    • fun getSavedEntities(): 使用 Flow 封装返回的 List。Flow 是值的异步序列。Flow 通过异步操作(例如网络请求、数据库调用或其他异步代码),一次生成一个值(而不是一次生成所有值)。它的 API 支持协程,因此也可以使用协程来完善 Flow。
    • @Query("SELECT * test_table ORDER BY word ASC"):可返回按升序排序的字词列表的查询。

    step4:实现room数据库。

    Room 数据库类必须是抽象且必须扩展 RoomDatabase。整个应用通常只需要一个 Room 数据库实例。

    @Database(entities = arrayOf(TestEntity::class), version = 1, exportSchema = false)
            public abstract class TestRoomDatabase : RoomDatabase() {
        abstract fun wordDao(): TestDao
    
        companion object {
            @Volatile
            private var INSTANCE: TestRoomDatabase? = null
            fun getDatabase(context: Context): TestRoomDatabase {
           
                return INSTANCE ?: synchronized(this) {
                    val instance = Room.databaseBuilder(
                        context.applicationContext,
                        TestRoomDatabase::class.java,
                        "test_database"
                    ).build()
                    INSTANCE = instance
                    // return instance
                    instance
                }
            }
        }
    
    }
    
    
    • Room 数据库类必须是 abstract 且扩展 RoomDatabase.
    • 您可以通过 @Database 将该类注解为 Room 数据库,并使用注解参数声明数据库中的实体以及设置版本号。每个实体都对应一个将在数据库中创建的表。数据库迁移这里不介绍了,因此这里已将 exportSchema 设置为 false 以免显示 build 警告。在真实的应用中,可以考虑为 Room 设置一个用于导出架构的目录,以便将当前架构签入版本控制系统。
    • 数据库会通过每个 @Dao 的抽象“getter”方法公开 DAO。
    • 定义了一个单例TestRoomDatabase,,以防出现同时打开数据库的多个实例的情况。
    • getDatabase 会返回该单例。首次使用时,它会创建数据库,具体方法是:使用 Room 的数据库构建器在 TestRoomDatabase 类的应用上下文中创建 RoomDatabase 对象,并将其命名为 "word_database"。

    step5:实在Repository中使用DAO

    class TestRepository(private val testDao: TestDao) {
    
        val allEntities: Flow<List<TestEntity>> = testDao.getSavedEntities()
    
       
        @WorkerThread
        suspend fun insert(entity: TestEntity) {
            testDao.insert(entity)
        }
    }
    
    

    step6:实在ViewModel中使用Repository

    这里利用了Hilt。首先在viewModel中查询所有结果,并且将flow转化为liveData,在需要的activity中注册监听。当数据库数据发生变化时,监听器就能收到相应的更改数据,比如调用insert之后

    @HiltViewModel
    class TestViewModel @Inject constructor(private val repository: TestRepository) :ViewModel() {
        val allWords: LiveData<List<Word>> = repository.allEntities.asLiveData()
    
        fun insert(entity: TestEntity) = viewModelScope.launch {
            repository.insert(entity)
        }
    }
    
    

    以上就是Room的简单使用。

    相关文章

      网友评论

          本文标题:Android中Room的使用

          本文链接:https://www.haomeiwen.com/subject/adfhydtx.html