简介

Room库在SQLite上提供了一个抽象层,允许在充分利用SQLite的功能的同时进行更健壮的数据库访问。可以在运行的app设备上创建一个应用数据缓存,这个缓存作为app的唯一数据来源,不管用户是否有连接网络,都允许用户在app中查看相关信息。
Room有三个主要的组成部分:Database,Entity,DAO。

  • Database:数据库容器,并作为到应用程序的持久关系数据的底层连接的主要访问点。

    使用@Database注释的类应该满足以下条件:

    • 扩展RoomDatabase的抽象类
    • 在注释中包含与数据库关联的实体列表
    • 包含一个具有0个参数的抽象方法,并返回用@Dao注释的类

在运行时,您可以通过调用Room.databaseBuilder()或Room.inMemoryDatabaseBuilder()来获取数据库实例。

  • Entity:表示数据库中的表。
  • DAO:包含用于访问数据库的方法。

图片
Room不同组成的相关关系图

引用

在project的build.gradle添加google的maven仓库

allprojects {repositories {google()jcenter()}
}

在module的build.gradle添加Room的引用,Room还提供了Rxjava2和Guava的数据处理

dependencies {def room_version = "2.1.0-alpha07"implementation "androidx.room:room-runtime:$room_version"annotationProcessor "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of annotationProcessor// optional - Kotlin Extensions and Coroutines support for Roomimplementation "androidx.room:room-ktx:$room_version"// optional - RxJava support for Roomimplementation "androidx.room:room-rxjava2:$room_version"// optional - Guava support for Room, including Optional and ListenableFutureimplementation "androidx.room:room-guava:$room_version"// Test helperstestImplementation "androidx.room:room-testing:$room_version"
}

Enity

下面定义一个User的实体

@Entity
data class User(@PrimaryKey val uid: Int,@ColumnInfo(name = "first_name") val firstName: String?,@ColumnInfo(name = "second_name") val secondName: String?,@Ignore val desc: String?
)
  • **表名:**Room使用实体类的名字作为数据库表的名字,如果想更改表名,可以使用@Entity(tableName = “users”)更改。
  • **主键:**每个实体都需要定义最少一个主键,可以直接在字段使用@PrimaryKey标注主键,想Room分配自动ID可使用autoGenerate属性,也可以使用复合主键@Entity(primaryKeys = [“second_name”,“first_name” ])
  • **字段名:**字段的名字默认的也是类中属性的名字如果想设置其他名字,可使用@ColumnInfo(name = “first_name”),Room为每个字段在表中创建对应的字段;如果其中一些属性不想被创建在表中怎么办,那就是使用 @Ignore 注解此属性
  • **索引和唯一约束:**使用 @Entity 的 indices 来创建索引,并列出索引或者组合索引包含的列,可以使用unique属性设置唯一约束Index(value = [“name”], unique = true)
@Entity(indices = [Index("name"), Index(value = ["first_name", "second_name"])])
data class User(@PrimaryKey val uid: Int,@ColumnInfo(name = "first_name") val firstName: String?,@ColumnInfo(name = "second_name") val secondName: String?,@Ignore val desc: String?
)
  • **外键:**可以使用@ForeignKey 定义对象间的级联操作
@Entity(foreignKeys = [ForeignKey(entity = User::class, parentColumns = ["uid"], childColumns = ["user_id"])])
data class Order(@PrimaryKey val orderNo: String,@ColumnInfo val address: String,@ColumnInfo(name = "user_id") val userId: Int
)
  • **嵌套对象:**可以使用@Embedded 嵌套其他实体对象,可以通过设置属性 prefix 加前缀的方式保证字段名不重复。
@Embedded(prefix = "order") val order: Order?

DAO

定义一个User的数据访问类

@Dao
interface UserDao {@Query("SELECT * FROM user")fun getAll(): List<User>@Query("SELECT * FROM user WHERE uid IN (:userIds)")fun loadAllByIds(userIds: IntArray): List<User>@Query("SELECT * FROM user where first_name LIKE :first AND second_name LIKE :last LIMIT 1 ")fun findByName(first: String, last: String): User@Insertfun insertAll(vararg users: User)@Deletefun delete(user: User)@Updatefun updateUsers(vararg users: User)
}
  • **插入:**使用@Insert注解,Room将把所有的参数在一次事物中插入到数据库中,Insert的参数onConflict用来指定当发生冲突是的策略。比如将@Index的unique属性设置为true,当产生冲突时,默认情况下为OnConflictStrategy.ABORT会导致崩溃,这里设置为OnConflictStrategy.REPLACE,当发生冲突时替换老数据
  • **更新:**使用@Update注解方法,可以使用参数实体的值更新主键值和参数实体的主键相同的行
  • 删除:@Delete注解方法,可以删除主键值和参数实体的主键相同的行
  • 查询:@Query支持查询语句,删除语句和更新语句,不支持插入语句。传入参数使用“:参数名”来进行绑定。
    • 可观察查****询

在执行查询时,想让UI在数据更改时自动更新。可以在查询方法使用 LiveData 类行的返回值。当数据更新时 Room 会自动生成所需的代码已更新LiveData。

@Query("SELECT * FROM user WHERE uid IN (:userIds)")
fun getList(userIds: IntArray): LiveData<List<User>>
  • 响应查询

可以从定义的查询中返回 RxJava2 的 Publisher 和 Flowable 对象

@Query("SELECT * FROM user where first_name LIKE :first AND second_name LIKE :last LIMIT 1 ")
fun getByName(first: String, last: String): Flowable<User>

Database

@Database(entities = arrayOf(User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {abstract fun userDao(): UserDao
}

创建完完成后使用以下代码获取数据库实例,并且使用单例来访问

var db = Room.databaseBuilder(getApplicationContext(),AppDatabase::class.java, "database-name"
).build()

迁移数据库

在APP升级时可能需要更改数据库来策应新的功能。如果不希望数据库中的数据丢失,
Room 允许我们编写 Migration ,以此来迁移数据;如果使用fallbackToDestructiveMigration(),数据库的内容都被清空。
每个迁移类制定一个开始版本和结束版本。在运行时,Room会运行每个Migration类的migrate()方法,并使用正确的顺序将数据库迁移到更高版本。
首先,需要更新Database的版本号

@Database(entities = arrayOf(User::class), version = 2)
abstract class AppDatabase : RoomDatabase() {abstract fun userDao(): UserDao
}

其次添加一个version:1->2的migration

val MIGRATION_1_2: Migration = object : Migration(1, 2) {override fun migrate(database: SupportSQLiteDatabase) {database.execSQL("ALTER TABLE User " + " ADD COLUMN mobile TEXT")}
}

最后把migration 添加到 databaseBuilder,addMigrations提供可选参数,支持多版本迁移,传入多个migration。

var db = Room.databaseBuilder(getApplicationContext(),AppDatabase::class.java, "database-name"
).allowMainThreadQueries().addMigrations(MIGRATION_1_2).build()

Room的基本用法介绍已经END。

Android Room使用相关推荐

  1. Unity5.6+ 导出Android 应用程序apk的环境配置及导出过程

    首先下载并安装安卓SDK和java的JDK 安卓sdk下载: http://www.android-studio.org/ 也可以在这下载: 链接:http://pan.baidu.com/s/1bp ...

  2. Android 的NDK的Makefile编写

    Android.mk 是google根据Linux GNU Makefile精简编译脚本.具体来说:这就是GNU Makefile的一小部分. 举一个简单例子: LOCAL_PATH := $(cal ...

  3. Android Animation (安卓动画)概念简介

    Android Animation Android 四种动画分别为逐帧动画和补间动画.属性动画.过渡动画: Frame Animation (逐帧动画) 实现方式:xml 和 Java代码 图片跳转的 ...

  4. 基于Android和SpringBoot的购物App

    (Shopping)购物应用商城 本软件使用Android和SpringBoot.JavaWeb技术实现:并结合百度LBS平台的SDK.支付宝App支付客户端SDK.MobTech的ShareSDK: ...

  5. Android数据持久化:SharePreference

    SharePreference:作为Android数据持久化的一种,具有一定的便捷性,适合存储一些体积小的数据. 存储数据方式:键值对的方式,类似于Map: 利用SharePreference.Edi ...

  6. Android数据持久化:文件存储

    数据持久化: 数据可分为瞬时数据和关键数据.保存在内存之中的数据是瞬时数据,而对于一些关键性数据,后期需要持续使用的,应当保存在存储设备中: 持久化保存方式: 文件存储.SharePreference ...

  7. Android Studio中RecycerView依赖库加载问题

    依赖包导入思考: 参考资料:recycleview导包问题 打开修改本项目中的build.gradle; 切勿着急添加包,应当提前查看其中的版本号(因为加载的v7包要和其版本保持一致性): 例如: 因 ...

  8. Android布局优化之include、merge、ViewStub

    include:引入重复使用的相同布局 merge:减少include布局的层级,将子元素直接添加到merge标签的parent中 ViewStub:其实就是一个宽高都为0的一个View,它默认是不可 ...

  9. Android动画之帧动画和补间动画

    Android系统提供三种动画:帧动画.补间动画和属性动画.这里先分析总结帧动画和补间动画. FrameAnimation 帧动画,通俗来说就是按照图片动作顺序依次播放来形成动画,创建帧动画可以用 x ...

  10. Android系统的启动过程

    Android系统的启动过程可以简单地总结为以下几个流程: 加载BootLoader -> 初始化内核 -> 启动init进程 -> init进程fork出Zygote(孵化器)进程 ...

最新文章

  1. R语言定量变量组间差异检验
  2. python3 issubset 判断列表子集
  3. 16.异常处理机制:exception
  4. 【Pytorch神经网络基础理论篇】 01 从零开始介绍深度学习算法和代码实现
  5. tomcat 9 无法启动_运维常见问题汇总tomcat篇
  6. Python 标准库 —— 文件解压(zip、gz、pkl、tar)
  7. python和c++哪个好-python和C++语言哪个好?老男孩教育
  8. [CQOI2015]选数
  9. WPF的错误以及笔记
  10. 封装出现 用户.计算机,系统封装教程 会电脑就会封装 | 一堵墙
  11. 【狂神说】Spring学习笔记(全)
  12. PDF转CAD格式步骤再简单
  13. 如何解决ueditor乱码问题
  14. Unity Predefined assemblies/assembly definition files
  15. 半导体技术科普:解读第三代半导体及宽禁带半导体
  16. Jest测试语法系列之Expect
  17. 110道python面试笔试题汇总,你能答对几道?
  18. 撩课小程序(教育类)实战存档(小程序 + 云开发)
  19. ROS wiki learn 整理 1
  20. 笔记本Win10超简单hdmi线链接树莓派

热门文章

  1. 共阴极数码管,学号显示实验
  2. Python Data mining - Enron Email Dataset
  3. UTC时间和CST时间
  4. php hapijs,hapi 起步
  5. 关于部署OOS时出现的证书问题解决
  6. 用python放音乐_python怎么播放音乐
  7. 使用ECharts加载大数据量数据
  8. kafka-eagle 使用配置及远程jmx端口设置遇到的问题
  9. 谨慎使用达梦manger工具
  10. 很多人都说flash as3 经常都是使用MC或者sprite(请问这里的sprite是什么意思?)...