美文网首页
Room 常用语法

Room 常用语法

作者: NewNiu | 来源:发表于2023-04-12 11:21 被阅读0次
    先以一个例子看下效果
    @Dao
    interface Dao {
    //----增
        // 添加一条数据
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        fun insert(data :Data)
        // 添加一个集合
        @Insert(onConflict = REPLACE)
        @JvmSuppressWildcards
        fun insert(list : MutableList<NewsBeanResponse>)
    
    //----删
        // 根据条件删除指定条目
        @Query("DELETE FROM Data WHERE data_key = :key")
        fun delete(key: String)
        // 删除所有数据
        @Query("DELETE FROM Data")
        fun deleteAll()
    
    //----改
    
    //----查
        // 根据word正序排序
         @Query("SELECT * FROM Data ORDER BY word DESC")
        fun getAllWords() : LiveData<List<Data>>
    
        // 只查一条数据
        @Query("SELECT * FROM Data WHERE type = :_type")
        fun getConfigByAdType(_type : Int) : Data?
    
        // 根据last_time大小正序查询limit条数据
        @Query("SELECT * FROM SearchRecord ORDER BY last_time DESC LIMIT :limitNum")
        fun getWords(limitNum : Int) : LiveData<List<SearchRecord>>
    
         // 复杂查询  -查询最后limit条数据按正序排列
        @Query("SELECT * FROM (SELECT * FROM NewsFeedData WHERE type = :type AND channelName = :channelName ORDER BY id DESC LIMIT :limit) 'linshi' ORDER BY id")
        fun loadData(type : Int,channelName : String,limit: Int) : List<NewsBeanResponse>
    }
    
    room 中在插入数据方法上加@Insert(onConflict = OnConflictStrategy.REPLACE)的作用是什么?

    @Insert(onConflict = OnConflictStrategy.REPLACE) 注解用于在插入数据时指定冲突策略。如果数据库中已经存在相同的记录(即主键或唯一约束列值相同),那么根据指定的冲突策略来处理这个冲突。

    在这里,指定的冲突策略是 OnConflictStrategy.REPLACE,表示如果存在冲突,则用新数据替换旧数据。换句话说,如果插入的记录已经存在于数据库中,那么将使用新记录替换旧记录,而不是插入一个新记录。

    使用该注解的好处是可以避免插入重复的数据,并且可以确保每次插入的数据都是最新的。这在一些需要频繁更新数据的场景中非常有用,例如缓存最新的数据。

    以下是一个示例:

    @Entity
    data class User(
        @PrimaryKey val id: Int,
        val name: String,
        val age: Int
    )
    
    @Dao
    interface UserDao {
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        suspend fun insert(user: User)
    }
    
    val userDao = appDatabase.userDao()
    
    // 新增一个用户
    val user = User(1, "John Doe", 30)
    userDao.insert(user)
    
    // 更新用户信息
    val updatedUser = User(1, "John Smith", 35)
    userDao.insert(updatedUser) // 会用新数据更新旧数据
    

    在这个例子中,UserDao 的 insert 方法上使用了 @Insert(onConflict = OnConflictStrategy.REPLACE) 注解。如果插入的用户已经存在于数据库中,则会用新的用户数据更新旧的用户数据。

    总的来说,@Insert(onConflict = OnConflictStrategy.REPLACE) 注解提供了一种简单的方法来避免插入重复的数据,并保证每次插入的数据都是最新的。


    除了onConflict = OnConflictStrategy.REPLACE,room还提供什么策略?

    除了 OnConflictStrategy.REPLACE,Room 还提供了其他几种冲突策略,以便根据具体的需求选择合适的策略。以下是 Room 支持的冲突策略列表:

    OnConflictStrategy.ABORT:默认的冲突策略。如果发生冲突,则会抛出 SQLiteConstraintException 异常。
    OnConflictStrategy.FAIL:与 ABORT 类似,但是不会抛出异常。而是会直接导致事务回滚。
    OnConflictStrategy.IGNORE:如果插入的记录已经存在,则不执行插入操作,也不会抛出异常。这种策略通常用于忽略一些无关紧要的数据冲突。
    OnConflictStrategy.REPLACE:如果存在冲突,则用新数据替换旧数据。
    OnConflictStrategy.ROLLBACK:与 FAIL 类似,但是会撤销所有未提交的事务。

    使用这些冲突策略时,需要根据具体的业务场景和数据要求来选择合适的策略。例如,如果要避免插入重复的数据,可以使用 OnConflictStrategy.IGNOREOnConflictStrategy.REPLACE;如果需要确保每次插入的数据都是最新的,可以使用 OnConflictStrategy.REPLACE;如果需要保证数据完整性,可以使用 OnConflictStrategy.FAILOnConflictStrategy.ROLLBACK

    以下是一个示例,演示了 Room 使用不同的冲突策略的方法:

    @Entity
    data class User(
        @PrimaryKey val id: Int,
        val name: String,
        val age: Int
    )
    
    @Dao
    interface UserDao {
        @Insert(onConflict = OnConflictStrategy.IGNORE)
        suspend fun insert(user: User)
    
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        suspend fun insertOrUpdate(user: User)
    
        @Insert(onConflict = OnConflictStrategy.FAIL)
        suspend fun insertOrFail(user: User)
    
        @Insert(onConflict = OnConflictStrategy.ROLLBACK)
        suspend fun insertWithRollback(user: User)
    }
    
    val userDao = appDatabase.userDao()
    
    // 新增一个用户
    val user = User(1, "John Doe", 30)
    userDao.insert(user)
    
    // 忽略重复数据
    val sameUser = User(1, "John Doe", 30)
    userDao.insert(sameUser) // 不会执行插入操作
    
    // 使用新数据更新旧数据
    val updatedUser = User(1, "John Smith", 35)
    userDao.insertOrUpdate(updatedUser) // 会用新数据更新旧数据
    
    // 插入重复数据会抛出异常
    userDao.insertOrFail(user) // 抛出异常
    
    // 插入重复数据会回滚所有事务
    userDao.insertWithRollback(user) // 会回滚所有事务
    

    什么是插入重复数据会回滚所有事务?

    在 Room 中,如果在执行 INSERT 操作时遇到了冲突,并且采用了 OnConflictStrategy.ROLLBACK策略,那么 Room 会撤销所有未提交的事务,以保证数据的一致性和完整性。

    事务是指一系列数据库操作,这些操作在执行过程中作为一个单一的操作单元,要么全部执行成功,要么全部撤销,以保证数据库的一致性和可靠性。在 Room 中,开发者可以通过 @Transaction 注解来定义事务方法,以确保这些操作在一个事务中执行。如果在一个事务中执行了多个操作,其中任意一个操作失败,那么这个事务就会失败,并且所有的操作都会被撤销,以回到事务开始的状态。

    当使用OnConflictStrategy.ROLLBACK 策略时,如果在执行 INSERT 操作时发生了冲突,那么这个操作所在的事务以及所有未提交的事务都会被撤销。这样可以保证数据的完整性和一致性,避免数据出现不一致的情况。

    下面是一个示例,演示了使用 OnConflictStrategy.ROLLBACK 策略时 Room 如何回滚事务:

    @Dao
    interface UserDao {
        @Insert(onConflict = OnConflictStrategy.REPLACE)
        suspend fun insert(users: List<User>)
    
        @Insert(onConflict = OnConflictStrategy.ROLLBACK)
        suspend fun insertWithRollback(user: User)
    }
    
    val userDao = appDatabase.userDao()
    
    // 定义一个事务方法
    @Transaction
    suspend fun insertUsers(users: List<User>) {
        userDao.insert(users)
        // 向数据库中插入一个重复数据,会导致事务回滚
        userDao.insertWithRollback(users.first())
    }
    
    // 向数据库中插入多条数据
    val users = listOf(
        User(1, "John Doe", 30),
        User(2, "Jane Smith", 25),
        User(3, "Tom Brown", 40)
    )
    insertUsers(users) // 会回滚所有事务
    

    在这个例子中,我们在一个事务方法 insertUsers 中插入了多条数据,并且在其中插入了一个重复数据。由于使用了 OnConflictStrategy.ROLLBACK 策略,因此当插入重复数据时,整个事务以及所有未提交的事务都会被回滚,因此数据库中不会留下任何数据。

    相关文章

      网友评论

          本文标题:Room 常用语法

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