前言
google官方的数据库框架,可以无缝结合LiveData以及Rxjava结合使用。
文档:Romm doc
api详细:Room summary
基础使用步骤
引入依赖,开启androidx哦
1 | dependencies { |
- 定义实体类 -
Entity
- 定义Dao类 -
Dao
- 定义抽象数据库类 -
Database
- 使用
定义实体
实体类对应着一张表
1 |
|
定义Dao
1 |
|
定义room数据库
1 | 1) (entities = {User.class}, version = |
使用
1 | AppDatabase db = Room.databaseBuilder(getApplicationContext(), |
定义实体
基础注解
@Entity
标注为实体@PrimaryKey
标注为主键@ColumnInfo
附加字段信息,比如字段名@Ignore
标注为忽略属性
使用@Entity
标注实体类,属性皆为对应表字段,前提是要JavaBean
,要么属性public,要么提供set/get方法。
使用@PrimaryKey
标注主键,autoGenerate
值设置自增
1 |
|
可以在@Entity
中设置主键
1 | "firstName", "lastName"}) (primaryKeys = { |
默认是以类名为表名,可以自定义表名,
1 | "users") (tableName = |
SQLite中表名忽略大小写的
自定属性对应字段名,使用@ColumnInfo
1 | "users") (tableName = |
忽略属性,从而不对应表字段,使用@Ignore
1 |
|
同样可以在@Entity声明
1 | "picture") (ignoredColumns = |
查询支持
FTS支持
FTS:Full Text Search 全文检索
要求:sdk大于16,Room2.1以上可以Fts3,Fts4
1 | // Use `@Fts3` only if your app has strict disk space requirements or if you |
使用languageId来指定字段来存储多语言信息。
1 | "lid") 4(languageId = |
索引支持
如果app的sdk版本不支持FTS,为了加快查询速度,可以考虑使用索引,使用@Index
1 | "name"), (value = {"last_name", "address"})}) (indices = { ( |
索引唯一,添加unique属性
1 | "first_name", "last_name"}, unique = true)}) (indices = { (value = { |
支持AutoValue对象
啥是AutoValue?
AutoValue说明,我看了下文档,大概意思就是说书写JavaBean类,需要写很多get/set,equals等大量模板代码,通过使用@AutoValue
注解一个抽象类,书写关键代码,模板代码交由注解处理器生成。
1 | import com.google.auto.value.AutoValue; |
通过apt注解处理器帮你生成大量的模板代码。诶,这不是和kotlin的Data类挺像的吗。hia~~
而Room使用AutoValue也很简单,某些标注了注解的地方,一定要加上@CopyAnnotations
1 |
|
定义对象关系
Room不允许对象引用
一对多
一对多的话就是通过外键制约。比如说一个人可以有多本书,一本书只能属于一个人。
通过@ForeignKey
定义外键,外键作用在于能够限定两条数据的级联操作
onUpdate
onDelete
有这么几种值,也是数据库的知识,提下就行了
1 | int NO_ACTION = 1; |
具体
1 | (foreignKeys = (entity = User.class, |
多对多
即比如一个歌单有n首歌,一首歌可以属于n个歌单
定义实体
1 |
|
多对多关联需要一个中间实体
1 | "playlist_song_join", (tableName = |
通过中间实体来映射多对多操作
1 |
|
内嵌对象
试着想下这么一个实体,比如人的信息,可以在次分割成小的对象表示,比如通过邮编,街道,街牌标注地址对象
1 | public class Address { |
这样生成表结构也是一样的,更加解耦,更加好理解,以及使用了。
创键视图
sql 里面视图是用户查询使用的,实际生成的表结构也是通过查询的出来,实际上不存在。
使用@DatabaseView
创键一个视图实体,只能用于查询。
1 | "SELECT user.id, user.name, user.departmentId," + ( |
在数据库中关联
1 | (entities = {User.class}, views = {UserDetail.class}, |
使用Dao
@Dao
可以注解接口和抽象类,取决于是否需要构造。默认dao的查询不能再主线程中,但是可以通过allowMainThreadQueries()
再构建器中构建,或者异步的查询考虑返回LiveData
或者Flowable
。
insert
使用@Insert
来标注插入操作
1 |
|
插入方法可以返回long的值,这个值就是插入Id,如果是插入集合的话,返回的也就是long[]或则List<Long>
update
根据主键去匹配行,可以返回int
表示所影响的行数
1 |
|
delete
通过主键去匹配行,可以返回int
表示所影响的行数
1 |
|
Query
简单查询
1 |
|
带参
使用:minAge
占位参数
1 |
|
多个占位参数
1 |
|
查询的部分字段
有时候你不需要获得全部字段,只需要部分字段
定义部分字段POJO,不需要用@Entity
哟
1 | public class NameTuple { |
使用
1 |
|
传入集合
1 |
|
可观察数据
返回LiveData
1 |
|
RxJava支持
首先需要加入RxJava支持依赖
1 | dependencies { |
可以返回被压Flowable
,Maybe
,Completeable
,Single
等
1 |
|
详情见 Room and RxJava
返回Cursor
当然了,对原来的Cursor游标也是支持返回的
非常不提倡使用Cursor
,因为游标不保证能查询的行存在,以及行内元素存在,除非你的项目期待使用游标,或者重构困难才考虑返回游标
1 |
|
多表联合查询
允许多表联合查询,同时允许返回LiveData
和Flowable
等可观察数据
1 |
|
允许使用POJO
1 |
|
使用kotlin协程
suspend
1 |
|
声明事务
1 |
|
类型转换器
定义类型转化器
1 | public class Converters { |
使用
1 | 1) (entities = {User.class}, version = |
自动将Java的Date和数据库中的时间戳互相转化
数据库迁移
待补充
数据库测试
待补充