Realm在android的应用
Realm 是一个移动数据库,可运行于手机、平板和可穿戴设备之上。可以让你的应用更快速,带来难以想象的体验。其目标是为了代替 CoreData 和 SQLite 数据库。
Realm 的优点
- 易用
Ream 不是在SQLite基础上的ORM,它有自己的数据查询引擎。并且十分容易使用。
- 快速
由于它是完全重新开始开发的数据库实现,所以它比任何的ORM速度都快很多,甚至比SLite速度都要快。
- 跨平台
Realm 支持 iOS & OS X (Objective‑C & Swift) & Android。我们可以在这些平台上共享Realm数据库文件,并且上层逻辑可以不用任何改动的情况下实现移植。
- 高级
Ream支持加密,格式化查询,易于移植,支持JSON,流式api,数据变更通知等高级特性
- 可视化
Realm 还提供了一个轻量级的数据库查看工具,在Mac Appstore 可以下载“Realm Browser”这个工具,开发者可以查看数据库当中的内容,执行简单的插入和删除数据的操作。
Realm的使用条件
- 目前不支持Android以外的Java
- Android Studio >= 1.5.1
- 较新的Android SDK版本
- JDK version >=7.
- 支持API 9(Android 2.3)以及之后的版本
1.加入依赖关系
(1)在project的build中加入依赖
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "io.realm:realm-gradle-plugin:2.2.1"
}
}
(2)在module中加入
apply plugin: 'realm-android
2.创建和初始化
(1)、使用RealmConfiguration配置Realm
创建数据库时首先需要调用Realm.init()方法,否则系统报错:java.lang.IllegalStateException: Call `Realm.init(Context)` before creating a RealmConfiguration
数据库初始化主要工作是什么数据库的name(设置数据库的文件名称)、schemaVersion(设置当前数据库版本号,当前版本号不能小于历史版本号)、migration(数据库版本迁移)、 deleteRealmIfMigrationNeeded(版本冲突时删除原始数据库)、inMemory(在内存中持久化,关闭后自动删除)、build(创建数据库)。
public static Realm getRealm(Context context) {byte[] key = new byte[64];new SecureRandom().nextBytes(key);Realm.init(context);Migration migration = new Migration();RealmConfiguration config = new RealmConfiguration.Builder().name("realmdb.realm") //文件名.schemaVersion(0) //版本号.migration(migration)//数据库版本迁移(数据库升级,当数据库中某个表添加字段或者删除字段).deleteRealmIfMigrationNeeded()//声明版本冲突时自动删除原数据库(当调用了该方法时,上面的方法将失效)。.build();//创建return Realm.getInstance(config); }
执行该方法后将生成一个文件名为:realmdb.realm的数据库文件。
(2)使用默认配置
Realm.init(this);Realm mRealm = Realm.getDefaultInstance();
使用默认配置将生成一个名为default.realm数据库文件
note:记得使用完后,在onDestroy中关闭Realm
@Override
protected void onDestroy() {
super.onDestroy();
// Close the Realm instance.
realm.close();
}
3、创建model
创建一个类名为User的model,首先该类必须继承自RealmObject,只有这才用使用Realm来操作model生成相应的表。
在Realm支持的类型有:boolean, byte, short,int,long,float, double,String, Date,byte[], RealmObject, RealmList<? extends RealmObject>还支持Boolean, Byte, Short, Integer, Long, Float 和 Double。但是:整数类型 short、int 和 long 都被映射到 Realm内的相同类型(实际上为 long )。
@PrimaryKey——表示该字段是主键
PrimaryKey就是主键。使用@PrimaryKey来标注,字段类型必须是字符串(String)或整数(byte,short,int或long)以及它们的包装类型(Byte,Short, Integer, 或 Long)。一个model中不可以存在多个主键,使用字符串字段作为主键意味着字段被索引(注释@PrimaryKey隐式地设置注释@Index)。
@Required——表示该字段非空
在某些情况下,某些属性是不能为null的。使用@Required可用于用于强行要求其属性不能为空,只能用于Boolean, Byte, Short, Integer, Long, Float, Double, String, byte[] 和 Date。在其它类型属性上使用 @Required修饰会导致编译失败。
note:基本数据类型不需要使用注解 @Required,因为他们本身就不可为空。
@Ignore——表示忽略该字段
如果想忽略某个字段,则可以使用@Ignore修饰该字段,被秀@ignore修饰的字段在存储数据时会忽略该字段。
@Index——添加搜索索引
使用@index可以为字段添加搜索索引,使用索引以后使得插入的速度变慢,数据量也变得更大。但是在查询速度将变得更快,所以建议只在优化读取性能的特定情况时添加索引。
支持索引:String,byte,short,int,long,boolean和Date字段。
public class User extends RealmObject {@PrimaryKeyprivate int id;private int age;@Requiredprivate String name;public int getId(){return id;}public void setId(int id){this.id = id;}public String getName(){return name;}public void setName(String name){this.name = name;}private RealmList<Dog> dogs;public RealmList<Dog> getDogs(){return dogs;}public void setDogs(RealmList<Dog> dogs){this.dogs = dogs;}public int getAge(){return age;}public void setAge(int age){this.age = age;} }
接下来开始数据库的CRUD操作了。
4、增
写入操作需要在事务中进行,
*使用executeTransaction方法来开启事务。
当model没有primaryKey时,可以使用下面的方法
mRealm.executeTransaction(new Realm.Transaction() {@Overridepublic void execute(Realm realm) {User user = realm.createObject(User.class);user.setName("Gavin");user.setAge(23);
user.setId(1);
}});
当model有primaryKey时,则可以使用下面的方法,将对@primaryKey修饰的字段直接在创建对象是赋值(createObject(User.class,1))
mRealm.executeTransaction(new Realm.Transaction() {@Overridepublic void execute(Realm realm) {User user = realm.createObject(User.class,1);user.setName("Gavin");user.setAge(23);
}});
*使用copyToRealmOrUpdate或copyToRealm方法插入数据
当model中含有primaryKey时使用copyToRealmOrUpdate插入数据,在当前插入主键的值存在时则修改对应主键值相关的数据信息,否则插入数据。
当model中不含有主键时,则使用copyToRealm。若在不含有主键的model中使用copyToRealmOrUpdate将抛异常:
java.lang.IllegalArgumentException: A RealmObject with no @PrimaryKey cannot be updated:XXXXX
final User user = new User();user.setName("李德华");user.setUserId("admin");user.setAge(25);user.setId(1);realm.executeTransaction(new Realm.Transaction(){@Overridepublic void execute(Realm realm){ realm.copyToRealmOrUpdate(user);}});
当在model(User)中包办另外一个model例如在User中包含一个Dog模型,也可以包含一个Dog的集合
还记得在之前的User数据模型中含有这么一块代码吗?这个申明表示一个User中可以包含(养)多条狗(Dog)
在Realm中List类型表示为RealmList。
private RealmList<Dog> dogs;public RealmList<Dog> getDogs(){return dogs;}public void setDogs(RealmList<Dog> dogs){this.dogs = dogs;}
向数据模型(User)插入另外一个数据模型(Dog)时,可以才用如下方式(当User含有主键时采用):
private void insertOrUpdateDataWithPrimaryKey() {final User user = new User();user.setName("李德华");user.setUserId("admin");user.setAge(25);user.setId(1);realm.executeTransaction(new Realm.Transaction(){@Overridepublic void execute(Realm realm){Dog dog1 = new Dog();dog1.setId(1);dog1.setAge(5);dog1.setName("藏獒");dogs = new RealmList<Dog>();dogs.add(dog1);user.setDogs(dogs);realm.copyToRealmOrUpdate(user);}}); }
当user没有主键时使用如下方式:
realm.executeTransaction(new Realm.Transaction() {
@Override public void execute(Realm realm) { User user = realm.createObject(User.class); user.setName("Gain"); user.setAge(23); Dog dog1 = realm.createObject(Dog.class); dog1.setAge(1); dog1.setName("二哈"); user.getDogs().add(dog1); Dog dog2 = realm.createObject(Dog.class); dog2.setAge(2); dog2.setName("阿拉撕家"); user.getDogs().add(dog2); }});
*使用异步方式进行数据插入,具体的方式如下:
使用异步插入,可以检测数据是否插入成功,成功后可以使用new Realm.Transaction.OnSuccess()进行监测,失败可以使用new Realm.Transaction.OnError()监测。
/*** 异步执行* 向有主键的数据表中insert或update数据* 数据表中有当前主键时则执行update* 否者执行insert*/ private void insertOrUpdateDataWithPrimaryKeyAsync() {final User user = new User();user.setName("李德华");user.setUserId("admin");user.setAge(25);user.setId(1);task = realm.executeTransactionAsync(new Realm.Transaction(){@Overridepublic void execute(Realm realm){Dog dog1 = new Dog();dog1.setId(1);dog1.setAge(5);dog1.setName("藏獒");dogs = new RealmList<Dog>();dogs.add(dog1);user.setDogs(dogs);realm.copyToRealmOrUpdate(user);}}, new Realm.Transaction.OnSuccess(){@Overridepublic void onSuccess(){Logger.d("Success");}}, new Realm.Transaction.OnError(){@Overridepublic void onError(Throwable error){Logger.d("Error");}}); }
注意:如果当Acitivity或Fragment被销毁时,在OnSuccess或OnError中执行UI操作,将导致程序奔溃 。用RealmAsyncTask .cancel();可以取消事务,在onStop中调用,避免crash
@Override protected void onStop() {super.onStop();if (task != null && task.isCancelled()){task.cancel();} }
*将Json数据直接插入数据库
Realm有一个强大的功能就是将Json数据直接插入到相应的数据库,具体的代码入下:
/*** 将Json数据添加到数据表中*/ private void insertDataFromJson() {realm.executeTransaction(new Realm.Transaction(){@Overridepublic void execute(Realm realm){realm.createOrUpdateObjectFromJson(User.class, "{ id: 2, age: 50, name:\"sealong\",userId:\"admin\",dogs:[{id:5,name:\"龙骑士\",age:3},{id:6,name:\"猪骑士\",age:4},{id:7,name:\"马骑士\",age:5}]}");}}); }
Realm 解析 JSON 时遵循如下规则:
1.使用包含空值(null)的 JSON 创建对象:
2.对于非必须(可为空值的属性),设置其值为 null;
3.对于必须(不可为空值的属性),抛出异常;
4.使用包含空值(null)的 JSON 更新对象:
5.对于非必须(可为空值的属性),设置其值为 null;
6.对于必须(不可为空值的属性),抛出异常;
7.使用不包含对应属性的 JSON: * 该属性保持不变
5.删
Realm的删除,包含两个步骤,首先查找到相应的数据集合,在在集合中删除相应的数据,代码如下:
private void deleteData()
{ //先查找到数据 final RealmResults<User> userList = realm.where(User.class).findAll(); realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { userList.get(4).deleteFromRealm();//删除指定位置(第4条记录)的记录userList.deleteFromRealm(4);//删除指定位置(第4条记录)的记录 userList.deleteFirstFromRealm(); //删除user表的第一条数据 userList.deleteLastFromRealm();//删除user表的最后一条数据 userList.deleteAllFromRealm();//删除user表的全部数据 } }); }
6.改
改是通过先查找到相应的数据,然后再设置需要修改的相应的信息。
例如修改User表中name=sealong 并且Id=2的所有对象,并将其UserId设置为user的代码如下。
private void dataUpdate() {realm.executeTransaction(new Realm.Transaction(){@Overridepublic void execute(Realm realms){//先查找后得到User对象RealmResults<User> users = realm.where(User.class).equalTo("name", "sealong").equalTo("id", 2).findAll();for (User user : users){user.setUserId("user");}}}); }
7.查
查找常用的函数有:
findAll ---- 查询满足条件的所有记录
findAllAsync----异步查询(当数据量较大,可能会引起ANR的时候,就可以使用findAllAsync)
findFirst ---- 查询第一条数据
equalTo ---- 根据条件查询(多次使用该函数可以实现多条件查询)
sum ---- 对指定字段求和。
average ---- 对指定字段求平均值。
min ---- 对指定字段求最小值。
max ---- 对指定字段求最大值。count : 求结果集的记录数量。
findAll ---- 返回结果集所有字段,返回值为RealmResults队列
findAllSorted ---- 排序返回结果集所有字段,返回值为RealmResults队列
between ---- 指定字段的值在某区间内
greaterThan()|lessThan()----指定字段的值大于(小于)给定的值
greaterThanOrEqualTo() & lessThanOrEqualTo()----指定字段的值大于等于(小于等于)给定的值
equalTo() & notEqualTo() ---- 指定字段的值(不)等于
contains() ----指定字段的值包含某些字符(指定字段为String)
beginsWith() & endsWith() ----指定字段的值以给定的值开始(结束)
isNull() & isNotNull() ----指定字段的值(不)为null
isEmpty() & isNotEmpty() ----指定字段的值(不)为空
private void dataSelectUser(){RealmResults<User> users = realm.where(User.class).findAllSorted("id", Sort.DESCENDING);//按照id倒序排序long size = users.size();//返回数据的条数double average = users.average("age");//返回查询结果的中age的平均值long sum = users.sum("age").longValue();//返回查询结果中age的总数long min = users.min("age").longValue();//返回查询结果中age的最小值long max = users.max("age").longValue();//返回查询结果中age的最大值 }
8.数据库升级
当某个数据表需要加某些字段或者添加某些属性时,而且不删除之前的原始数据的情况下,需要对原始数据进行升级
例如需要对表删除字段age,并且需要添加一个String类型的userId 并且设置将之前表中的userId的值设置为1,同时版本号需要更新
public class Migration implements RealmMigration {/*** 升级数据库*/@Overridepublic void migrate(DynamicRealm realm, long oldVersion, long newVersion){RealmSchema schema = realm.getSchema();if (oldVersion != newVersion){RealmObjectSchema personSchema = schema.get("User");//新增@Required的idpersonSchema.addField("userId", String.class, FieldAttribute.REQUIRED).transform(new RealmObjectSchema.Function(){@Overridepublic void apply(DynamicRealmObject obj){obj.set("userId", "1");//为id设置值}}).removeField("age");oldVersion++;}} }
最后贴出本人测试的源代码:http://download.csdn.net/detail/sealong_/9741919
Realm在android的应用相关推荐
- realm android,Realm for Android快速入门教程
介绍 如果你关注安卓开发的最新趋势,你可能已经听说过 Realm .Realm是一个可以替代SQLite以及ORMlibraries的轻量级数据库. 相比SQLite,Realm更快并且具有很多现代数 ...
- Realm for Android 使用入门
Realm 是一个手机数据库,是用来替代 SQlite 的解决方案,比 SQlite 更轻量级,速度更快,因为它有一套自己的数据库搜索引擎,并且还具有很多现代数据库的优点,支持 JSON,流式 API ...
- realm教程 android,Realm for Android基本教程
8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? Realm是一款开源的数据库工具,它具有快速,易于使用和支持多平台的特点.它完全可以取代我们Android中的SQLit ...
- 【Android开发】【数据库】Realm For Android
目录 1.Realm简介 2.环境配置 3.初始化Realm 4.创建实体 5.增 6.删 7.改 8.查 9.异步操作 10.数据库数据更新监听 11.json转对象,插入数据库 12.Demo地址 ...
- 《Android开源库》 Realm For Android~ Queries(译文)
查询 Realm 中的所有读取(包括查询)操作都是延迟执行的,且数据绝不会被拷贝. Realm 的查询引擎使用 Fluent interface 来构造多条件查询. 使用 User 类 - publi ...
- Android数据库新王者-Realm入门教程
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010046908/article/details/51629262 好长时间没有写关于Androi ...
- Android Realm数据库
In this tutorial, we'll be discussing the basics of Realm Database and implement it in our Android A ...
- 【Android】Realm详解(Android 数据库Sqlite的完美替代者)
介绍 Realm 是一个 MVCC (多版本并发控制)数据库,由Y Combinator公司在2014年7月发布一款支持运行在手机.平板和可穿戴设备上的嵌入式数据库,目标是取代SQLite. Real ...
- android Realm 优化
Realm数据库优化 Realm数据的一个特点是支持跨平台操作,且效率上面比较高,是非关系数据库.但是在使用的过程中还是存在很多可以优化的控件,本文章重点解决Realm数据库无表信息和列信息,和Rea ...
- Android 开源框架选择
目录 一.前言 二.APP的整体架构 三.技术选型的考量点 四.日志记录能力 五.JSON解析能力 1.gson 2.jackson 3.Fastjson 4.LoganSquare 六.数据库操作能 ...
最新文章
- 基于RDKit的溶解度预测的机器学习模型
- linux 内核编译错误 undefined reference to '__mutex_lock_slowpath'
- 全局变量/static静态变量在section段中的分布
- python从数据库取数据保存为excel_python读取数据库表数据并写入excel
- 自由自在意式手工冰淇淋的清凉之风已“冰”临城下
- linux 安装软件_Linux:其它软件安装方式
- [JS-DOM]事件监听机制
- Windows内核函数
- Git Permission to fazhiyun86/Test.git denied to MarRoar
- 了解Base64编码的原理(js核对)
- MIT自适应律MRAC的理解和MATLAB实现
- c语言文件归档,Go语言tar归档文件的读写操作
- 使用mingw编译log4cpp--问题整理
- Excel如何统计多种分隔符号的单元格姓名个数
- java 考勤_java,添加一个类,显示考勤信息的。
- c语言中front是什么,front用法,关于front的用法
- 打破思维断层之KMP分析
- 申宝投资-三大股指开盘逐渐下跌
- Servlet - Filtering (过滤器))
- 现代 Web 开发的现状与未来
热门文章
- powerha_使用IBM PowerHA SystemMirror的Hitachi TrueCopy镜像
- python 标签云_Python中文标签云之pytagcloud
- Java 给PDF文件添加水印
- matlab求解微分方程ode23
- Fiddler抓包工具报:The system ptoxy changed. Click to reenable capturing
- 大数据技术学习带来的思考
- 图像曲率 与 黎曼几何
- pip install:Requirement already satisfied
- 产品线管理:学习笔记
- 云桌面-ThinVirt3-EXP操作手册(一)云桌面系统安装