Room 常用语法

先以一个例子看下效果
@Dao
interface Dao {
//----增
    // 添加一条数据
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insert(data :Data)
    // 添加一个集合
    @Insert(onConflict = REPLACE)
    @JvmSuppressWildcards
    fun insert(list : MutableList)

//----删
    // 根据条件删除指定条目
    @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>

    // 只查一条数据
    @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>

     // 复杂查询  -查询最后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
}
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)

    @Insert(onConflict = OnConflictStrategy.ROLLBACK)
    suspend fun insertWithRollback(user: User)
}

val userDao = appDatabase.userDao()

// 定义一个事务方法
@Transaction
suspend fun insertUsers(users: List) {
    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 常用语法)