Realm介绍
- Realm官网链接https://realm.io/
- 开源地址https://github.com/realm/realm-java
- 官方使用文档https://realm.io/docs/java/latest/
Realm是一个开源的ORM概念的(对象关系映射)移动数据库,可以在Android ,ios ,java各个平台上使用,性能秒杀sqlite等数据库比如(greendao)。
快速入门
只需两步
在项目的build.gradle中dependencies输入classpath “io.realm:realm-gradle-plugin:2.3.1”,这里要双引号。这里要双引号。这里要双引号。
1 | buildscript { |
在app的bulid.gradle输入apply plugin: ‘realm-android’
1 | apply plugin: 'realm-android' |
★以上操作完成了realm在as的配置了。
Realm的模型
自定义类要继承RealmObject,注意这里必须要有一个无参数的构造方法。
1 | public class Dog extends RealmObject { |
如果类A中包含着其他类的集合这时候要用到ResultList
1 | public class Person extends RealmObject { |
如果你的自定义类已经继承了其他父类,你也可以实现RealmModel来建造realm对象模型。
1 | @RealmClass |
Realm注解说明
@RealmClass 当实现RealmModel接口的类要加上这个注解。
@Required 修饰不能为空的成员变量
@Ignore 修饰不写入数据库的变量
@PrimaryKey 设置该成员变量为类的主键
@Index 加快查询速度,不过会让插入数据时变慢
Realm初始化
在自定义Applciation中Realm.init(this);
获取Realm实例
1 | realm = Realm.getDefaultInstance(); |
这是获取默认配置的Realm,默认保存在data/data/packageName/files/default.realm 你也可以自定义RealmConfiguration,通常是自定义文件名,加密的key,数据库版本号和是否删除合并前的数据等。Realm实现了closeable接口,所以每次的getInstance,到最后关闭使用后都要调用close方法。比如在activity的ondestroy调用realm.close();
Realm写入
Realm是一个MVCC架构,同一线程的读写操作不影响获取数据,但是多线程读取写入操作就要用到事务来确保获取数据一致性和线程安全。的是放在事务transcation里面执行,确保整个事务的操作都被提交或者全部取消操作调用realm.cancelTranscation();,确保数据的一致性。
1 | realm = Realm.getDefaultInstance(); |
♥copyToRealm会深拷贝一个变量到数据库包括主键,如果主键重复就会抛出异常,拷贝之后主键不能修改。
当两个线程同时进行写入操作,另外一个会造成主线程阻塞,所以要调用异步事务避免主线程阻塞。
1 | //同步新增数据 |
1 | //异步修改 查询 |
realm的主键,在oncreate方法加入设置主键的RealmObject方法,下次调用oncreate没有判断主键是否exist就加入数据库就会报错。而在oncreate方法没加入没设置主键的realmobject类 ,下次调用oncreate方法就会在自启动数据库文件追加。
Realm 查询
查询都是返回一个RealmResults
- between(),greaterThan(), lessThan(), greaterThanOrEqualTo() 和lessThanOrEqualTo();
- equalTo()和notEqualTo()
- contains(),beginsWith()和endsWith()
- isNull()和isNotNull()
- isEmpty()和isNotEmpty()
1 | RealmResults<Dog> list=realm.where(Dog.class).lessThan("age",1).findAll(); |
Realm修改
修改操作要在一个事务里面完成。
1 | dog = new Dog(1, "a", 1); |
RealmResult的changeListener
监听RealmResult内容变化。
1 | RealmResults<Dog> list = realm.where(Dog.class).lessThan("id", 3).findAll(); |
Realm的删除
继续上面的例子查询id小于3的realmresult集合
1 | list.addChangeListener(new RealmChangeListener<RealmResults<Dog>>() { |
Realm添加一个json字符串
1 | realm.executeTransaction(new Realm.Transaction() { |
copyFromRealm,copyToRealm和createObject区别
- copyFromRealm传入一个RealmObject 拷贝realm数据库中的一个变量并拷贝他的所有属性。
- copyToRealm 传入一个Obeject 拷贝这个Object的所有属性到realm数据库中
- createObject 传入一个class 并且赋值他的成员变量为默认值null 或者需要后期赋值使用
RealmResult 使用
1 | RealmResults<Dog> list = realm.where(Dog.class).findAll(); |
比如获取dog类的所有对象,求age的总和,最大值,最小值,平均值
DynamicRealm
DynamicRealm是Realm的变种类,可以操作没继承RealmObject的类,操作类,当然是以字符串的形式操作,而不是RealmObject,他的默认配置少了schema版本号,migration合并信息的检查。
1 | DynamicRealm dynamicRealm = DynamicRealm.getInstance(new RealmConfiguration.Builder().build()); |
Realm的close
Realm实现了closeable接口,所以每次的getInstance,到最后关闭使用后都要调用close方法。比如在activity的ondestroy调用realm.close();
比如在子线程getIntstance一次,需要在子线程结束前调用一次close();
1 | class MyRunnable implements Runnable{ |
Realm 版本迁移
如果realm版本是1,现在要升级realm版本是2并且数据解构改变了比如新增了一个RealmObejct的成员变量,如果default.realm存在旧数据,会升级失败。需要要设置migration合并规则。
要自定义一个RealmConfiguration变量 ,重写migrate方法判断oldVersion是上一个版本号,要做什么需求。
1 | //你还可以做以下操作 |
比如版本升级加上key
1 |
|
总结
- Realm很多种情况修改数据要配合事务使用。
- Realm以一个RealmObject作为一个表的功能。
- realm的getInstance和close要结对使用
- 需要注意RealmResult移除listener