Room-数据持久化存储(入门)
@
# 前言
官方简介:
Room 持久性库在 SQLite 的基础上提供了一个抽象层,让用户能够在充分利用 SQLite 的强大功能的同时,获享更强健的数据库访问机制。
引入库:
implementation "androidx.room:room-runtime:2.3.0"
kapt "androidx.room:room-compiler:2.3.0"
//kotlin 扩展库
implementation "androidx.room:room-ktx:2.3.0"
配置 build:
android {
...
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments += mapOf(
"room.schemaLocation" to "$projectDir/schemas",
"room.incremental" to "true",
"room.expandProjection" to "true"
)
}
}
}
}
提示:以下是本篇文章正文内容,下面案例可供参考
一、简单使用
万事开头难, 好记性不如烂笔头. 看十遍不如敲一遍.
所以 咱们先把代码敲起来.
1.Entity
@Entity
class RoomTwoEntity {
@PrimaryKey
var id: String = ""
@ColumnInfo
var nickname: String? = null
@ColumnInfo
var sex: Int = 0
@Ignore
var like = false
}
- @Entity: 表示数据库中的表
- @ColumnInfo: 表示table中的字段
- @Ignore: 表示忽略该字段, (不映射到表中)
细节后面再讲
2.Dao
@Dao
interface RoomTwoDao {
@Query("select * from RoomTwoEntity")
fun get(): MutableList<RoomTwoEntity>
@Insert(onConflict = OnConflictStrategy.REPLACE) //当冲突时: ABORT,取消; REPLACE,替换; IGNORE,忽略;
fun add(entity: RoomTwoEntity)
@Insert(onConflict = OnConflictStrategy.REPLACE) //当冲突时: ABORT,取消; REPLACE,替换; IGNORE,忽略;
fun addList(list: MutableList<RoomTwoEntity>)
@Delete
fun delete(entity: RoomTwoEntity)
@Update
fun update(entity: RoomTwoEntity)
@Query("delete from RoomTwoEntity where id = :id ") //删除也可以用 query
fun deleteById(id: String)
}
这代码是不是很好阅读!
普通增删改只需要一个注解. 查询需要写 sql
3.DataBase
@Database(entities = [RoomTwoEntity::class], version = 1)
abstract class RoomTestDatabase : RoomDatabase() {
abstract fun roomTwoDao(): RoomTwoDao
companion object {
private var instance: RoomTestDatabase? = null
fun getInstance(context: Context): RoomTestDatabase {
if (instance == null) {
instance = Room.databaseBuilder(
context.applicationContext,
RoomTestDatabase::class.java,
"Test.db" //数据库名称
)
// .allowMainThreadQueries() //主线程中执行
.fallbackToDestructiveMigration() //数据稳定前, 重建.
// .addMigrations(MIGRATION_1_2) //版本升级
.build()
}
return instance!!
}
}
}
4.使用
注意: 代码要在子线程中执行. 或者方便测试时打开 .allowMainThreadQueries()
//创建 10 条数据
private fun createTen(){
val list = mutableListOf<RoomTwoEntity>()
repeat(10){
list.add(RoomTwoEntity().apply {
id = "room$it"
nickname = "名字$it"
})
}
RoomTestDatabase.getInstance(mActivity).roomTwoDao().addList(list)
}
//查询数据
private fun query(): MutableList<RoomTwoEntity>{
return RoomTestDatabase.getInstance(mActivity).roomTwoDao().get()
}
//例如
GlobalScope.launch(Dispatchers.IO) {
createTen()
}
二、参数解析
1.Entity
1.1 @Entity
| 字段名 | 意义用法 |
|---|---|
| tableName (String) | table名, 默认Entity类名. |
| indices (Index[]) | 索引, 搞过数据库的都懂吧. 单列:indices = arrayOf(Index(value = ["last_name"])) 多列:indices = arrayOf(Index(value = ["last_name", "address"])) 多个索引:indices = arrayOf(Index(value = ["last_name"]),Index(value = ["address"])) Index.unique = true 索引项唯一 |
| inheritSuperIndices (boolean) | 是否继承父类的索引 |
| primaryKeys (String[]) | 主键. 单主键的时候可以定义在字段上. 复合主键的时候定义在类上. 它应该也能定义父类的字段. 示例: primaryKeys = arrayOf("firstName", "lastName") |
| foreignKeys | 外键 |
| ignoredColumns (String[]) | 忽略字段, 更容易的忽略父类字段 |
1.2 @ColumnInfo
这个注解默认可以省略
| 字段名 | 意义用法 |
|---|---|
| name | 列名, 默认就是属性名 |
| typeAffinity | 字段类型, 默认按属性类型自动生成. 还有 TEXT,INTEGER,REAL,BLOB |
| index (boolean) | 是否生成单列索引, 默认false |
| collate | 建表时 列的排序 |
| defaultValue | 列的默认值 |
1.3 @PrimaryKey
主键必须有, 且必须注解标出
每个实体必须将至少 1 个字段定义为主键。即使只有 1 个字段,您仍然需要为该字段添加 @PrimaryKey 注释。此外,如果您想让 Room 为实体分配自动 ID,则可以设置 @PrimaryKey 的 autoGenerate 属性。如果实体具有复合主键,您可以使用 @Entity 注释的 primaryKeys 属性.
2.Dao
2.1 onConflict
@Insert @Update 时:
新增或修改时, 假设与原有行数据冲突(例如主键冲突). 时的处理方式
| 值 | 用法 |
|---|---|
| OnConflictStrategy.REPLACE | 覆盖,替换 原有数据 |
| OnConflictStrategy.ABORT | (默认模式) 严格模式, 会让事务失败并回滚 |
| OnConflictStrategy.IGNORE | 非严格模式, 会忽略冲突行, 然后继续执行其他操作 |
2.2 还可以这样用:
@Dao
interface MyDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertUsers(vararg users: User) // java: (User... users)
@Insert
fun insertBothUsers(user1: User, user2: User) //多实体
@Insert
fun insertUsersAndFriends(user: User, friends: List<User>)
@Update
//可以让它返回一个 Int, 代表数据库中更新的行数
fun updateUsers(vararg users: User): Int
@Delete
fun deleteUsers(vararg users: User): Int //返回行数
}
2.3 @Query
以下搬运自官方文章:
@Query 是 DAO 类中使用的主要注释。它允许您对数据库执行读/写操作。每个 @Query 方法都会在编译时进行验证,因此如果查询出现问题,则会发生编译错误,而不是运行时失败。
Room 还会验证查询的返回值,以确保当返回的对象中的字段名称与查询响应中的对应列名称不匹配时,Room 可以通过以下两种方式之一提醒您:
如果只有部分字段名称匹配,则会发出警告。如果没有任何字段名称匹配,则会发出错误。
3.查询方式
它可以这样查: 冒号后写参数名.
@Query("SELECT * FROM user WHERE age > :minAge")
fun loadAllUsersOlderThan(minAge: Int): Array<User>
也可以这样查: 只查部分字段
@Query("SELECT first_name, last_name FROM user")
fun loadFullName(): List<NameTuple>
还可以这样查: 传入参数集合
@Query("SELECT first_name, last_name FROM user WHERE region IN (:regions)")
fun loadUsersFromRegions(regions: List<String>): List<NameTuple>
更可以这样查: 连表查询,复杂查询等
@Query(
"SELECT user.name AS userName, pet.name AS petName " +
"FROM user, pet " +
"WHERE user.id = pet.user_id"
)
fun loadUserAndPetNames(): LiveData<List<UserPet>>
// You can also define this class in a separate file.
data class UserPet(val userName: String?, val petName: String?)
虽然博主没测, 但这里 UserPet 估计是不需要 @Entity 的;
开启事务
@Transaction
@Dao
abstract class UsersDao {
@Transaction
open suspend fun setLoggedInUser(loggedInUser: User) {
deleteUser(loggedInUser)
insertUser(loggedInUser)
}
@Query("DELETE FROM users")
abstract fun deleteUser(user: User)
@Insert
abstract suspend fun insertUser(user: User)
}
因为DB操作必须要在子线程:
可以将 suspend Kotlin 关键字添加到 DAO 方法中,以使用 Kotlin 协程功能使这些方法成为异步方法。这样可确保不会在主线程上执行这些方法。
就写到这把, 篇幅有点长了, 剩下的下一篇再讲.
总结
room的使用可比直接用SQLite简单多了. 而且方便升级. 还能够配合Paging, 配合LiveData, FLow等使用.
上一篇: Paging3-分页数据加载库(结合room)
下一篇: Room-数据持久化存储(进阶)
Room-数据持久化存储(入门)的更多相关文章
- iOS数据持久化存储:归档
在平时的iOS开发中,我们经常用到的数据持久化存储方式大概主要有:NSUserDefaults(plist),文件,数据库,归档..前三种比较经常用到,第四种归档我个人感觉用的还是比较少的,恰恰因为用 ...
- iOS开发——数据持久化Swift篇&使用Core Data进行数据持久化存储
使用Core Data进行数据持久化存储 一,Core Data介绍 1,Core Data是iOS5之后才出现的一个数据持久化存储框架,它提供了对象-关系映射(ORM)的功能,即能够将对象转化成 ...
- Swift - 使用Core Data进行数据持久化存储
一,Core Data介绍 1,Core Data是iOS5之后才出现的一个数据持久化存储框架,它提供了对象-关系映射(ORM)的功能,即能够将对象转化成数据,也能够将保存在数据库中的数据还原成对象. ...
- vuex数据持久化存储
想想好还是说下vuex数据的持久化存储吧.依稀还记得在做第一个vue项目时,由于刚刚使用vue,对vue的一些基本概念只是有一个简单的了解.当涉及到非父子组件之间通信时,选择了vuex.只是后来竟然发 ...
- [Xcode 实际操作]七、文件与数据-(14)数据持久化存储框架CoreData的使用:删除CoreData中的数据
目录:[Swift]Xcode实际操作 本文将演示如何删除数据持久化对象. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit //引入数据持 ...
- [Xcode 实际操作]七、文件与数据-(13)数据持久化存储框架CoreData的使用:编辑CoreData中的数据
目录:[Swift]Xcode实际操作 本文将演示如何修改数据持久化对象. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit //引入数据持 ...
- [Xcode 实际操作]七、文件与数据-(12)数据持久化存储框架CoreData的使用:查找CoreData中的数据
目录:[Swift]Xcode实际操作 本文将演示如何查找数据持久化对象. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit //引入数据持 ...
- [Xcode 实际操作]七、文件与数据-(11)数据持久化存储框架CoreData的使用:创建CoreData实体并插入数据
目录:[Swift]Xcode实际操作 本文将演示[CoreData]数据持久化存储框架的使用. 点击[Create a new Xcode project]创建一个新的项目 ->[Single ...
- 转载 -- iOS数据持久化存储
作者:@翁呀伟呀 授权本站转载 概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方 ...
- iOS数据持久化存储之属性列表
属性列表(plist) iOS提供了一种plist格式的文件(属性列表)用于存储轻量级的数据,属性列表是一种XML格式的文件,拓展名为plist.如果对象是NSString.NSDictionary. ...
随机推荐
- Java学习之jackson篇
Java学习之jackson篇 0x00 前言 本篇内容比较简单,简单记录. 0x01 Json 概述 概述:JSON(JavaScript Object Notation, JS 对象简谱) 是一种 ...
- JavaScrip条件表达式优化
目录 1,前言 2,多条件if语句优化 3,参数默认值 4,Switch语句优化 1,前言 今早看了一篇文章<JavaScrip实现:如何写出漂亮的条件表达式>,原创于:华为云开发者社区, ...
- Spring Boot & Cloud 轻量替代框架 Solon 1.4.1 发布
Solon 是一个微型的Java开发框架.强调,克制 + 简洁 + 开放的原则:力求,更小.更快.更自由的体验.支持:RPC.REST API.MVC.Micro service.WebSocket. ...
- SE_Work4_软件案例分析
项目 内容 课程:北航-2020-春-软件工程 博客园班级博客 要求:分析软件案例 个人博客作业-软件案例分析 班级 005 这个作业在哪个具体方面帮助我实现目标 分析对比一类软件,学会规划分析软件的 ...
- MSSQL·查询T-SQL语句执行时间的三种方法
阅文时长 | 0.23分钟 字数统计 | 420.8字符 主要内容 | 1.引言&背景 2.自定义时间变量求差法 3.MSSQL内置方法 4.MSSQL选项开启时间统计 5.声明与参考资料 『 ...
- Linux_配置主DNS服务(基础)
[RHEL8]-DNSserver:[Centos7.4]-DNSclient !!!测试环境我们首关闭防火墙和selinux(DNSserver和DNSclient都需要) [root@localh ...
- 003.Python数据类型转换
一 自动类型转换 (针对于Number类型) bool float int complex 当Number不同的数据类型进行运算的时候,默认向更高精度转化 精度从低到高顺序:bool -> in ...
- 10.21 nmap:网络探测工具和安全/端口扫描器
nmap命令 是一款开放源代码的网络探测和安全审核工具,是Network Mapper的缩写.其设计目标是快速地扫描大型网络.nmap可以发现网络上有哪些主机,主机提供了什么服务(应用程序名称和版本号 ...
- Ubuntu下安装与卸载Nginx
1.Ubuntu下安装Nginx比较简单 敲入下列命令即可: sudo apt-get update sudo apt-get install nginx 2.Ubuntu下卸载,稍不注意就会入坑 s ...
- Java枚举类与注解详解——一篇文章读懂枚举类与注解详
目录 一.枚举类 ① 自定义枚举类 ② enum关键字定义枚举类 ③ enum 枚举类的方法 ④ enum 枚举类实现接口 二.注解 ① 生成文档相关注解 ②注解在编译时进行格式检查 ③注解跟踪代码的 ...