Room 常用语法

先以一个例子看下效果
@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 策略,因此当插入重复数据时,整个事务以及所有未提交的事务都会被回滚,因此数据库中不会留下任何数据。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,192评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,186评论 1 303
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,844评论 0 252
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,471评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,876评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,891评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,068评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,791评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,539评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,772评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,250评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,577评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,244评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,146评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,949评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,995评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,812评论 2 276

推荐阅读更多精彩内容