Realm数据库的使用
文章目录
- 写在前面
- 简单使用
- 几个概念
- 1. 数据模型
- 2. 事务
- 3. 引用计数
- 4. 数据库的迁移
- 添加配置文件
- 初始化Realm并配置Realm
- 1. 在application的`onCreate()`中使用`Realm.init()`初始化
- 2. 在application的`onCreate()`中对Realm进行相关的配置
- 3. Realm使用完了之后要关闭
- 创建模型
- 字段类型
- 修饰符
- 事务
- 1. 手动开启事务
- 2. 同步事务执行块
- 3. 异步事务执行块
- 数据库操作-增
- 1. `copyToRealm()`/`createObject()`获取自动更新的Realm模型
- 2. `inset()` 或者 `inserOrUpdate()`
- 3. `createObjectFromJson()`
- 数据库操作-查
- 1. realm.where(User.class)
- 2. 条件过滤
- 3. 逻辑判断
- 4. findXxxx()
- 5. 其他用法
- 数据库操作-删
- 1. 使用`deleteFromRealm()`
- 2. 使用 deleteFromRealm(int index)
- 3. 其他方法
- 数据库操作-改
- 数据库的迁移
- 1. 写一个类继承`RealmMigration`,重写`migrate()`
- 2. 设置配置信息,并让Realm执行数据迁移动作
- 总结:
写在前面
Realm数据库不同于SQLite,两者可以说是同级的,为什么选择Realm数据库?Android目前流行三方数据库ORM分析及对比。我个人觉得最主要的是两点:1. 访问快,直接操作底层数据;2. 支持跨平台。什么是ORM? object relation model,对象关系映射模型,就是通过使用描述对象和数据库之间映射的元数据,来实现面向对象语言程序中的对象与关系数据库中数据的映射。简单来说,就是一个类对应数据库中的表,一个属性对应数据库中的一列,一个类的对象对应数据库中的一条记录。 参考。基于ORM技术的框架称为ORM框架,它使得使用者更容易理解和操作数据库,但是由于中间需要转换,所以性能上比直接使用SQL语句要慢,另外还需要保存数据对应的类,所以需要更多的内存。
简单使用
RealmGitHube 或者 官网。
几个概念
1. 数据模型
- 一个模型(java中的一个类)表示数据库中的一张表,模型中的字段表示表中的列
- 模型需要继承
RealmObjec
t类 - 模型实时、自动更新(需要获得当前线程的looper,在主线程中是满足的);操作模型就相当于直接操作数据库中底层数据
2. 事务
- 所有会使数据发生变化 的操作必须在事务中进行。如:增、删、改
- 事务分为同步事务和异步事务两种
3. 引用计数
- Realm实例使用引用计数的方式
- 生成的Realm实例在使用完后需要手动close。
4. 数据库的迁移
在Realm中如果增加、删除了模型或者模型的字段,需要进行数据库的迁移。这个概念类似于数据库的升级。
添加配置文件
- 在project的
build.gradle
文件中调加依赖
buildscript {repositories {jcenter()}dependencies {classpath "io.realm:realm-gradle-plugin:5.12.0"}
}
- 在app下的
build.gradle
文件顶部添加对应的插件支持
apply plugin: 'realm-android'
初始化Realm并配置Realm
1. 在application的onCreate()
中使用Realm.init()
初始化
2. 在application的onCreate()
中对Realm进行相关的配置
配置不是必须的,如果不配置,会使用默认配置;但是如果有数据库的迁移,那么是需要配置数据库的。
- 使用默认配置
有两种方式可以使用默认配置:
//方式1:
// Get a Realm instance for this thread
Realm realm = Realm.getDefaultInstance();
这样得到的Realm实例使用的就是默认的配置。
//方式二
RealmConfiguration config = new RealmConfiguration.Builder().build();
Realm.setDefaultConfiguration(conf);
默认配置的话,会得到一个名为default.realm
数据库,数据库保存地址:data/data/包名/files/default.realm
。
- 自定义配置
// The Realm file will be located in Context.getFilesDir() with name "myrealm.realm"
RealmConfiguration config = new RealmConfiguration.Builder().name("myrealm.realm").encryptionKey(getKey()) //设置密钥.schemaVersion(42) //版本号.modules(new MySchemaModule()).migration(new MyMigration()) //数据库迁移.build();
// Use the config
Realm realm = Realm.getInstance(config);
3. Realm使用完了之后要关闭
一般在activity.onDestroy()
中关闭,或者在finally语句块中关闭
try {// ... Use the Realm instance ...} finally {realm.close();}
创建模型
一般来说都是写一个类继承RealmObject
public class User extends RealmObject {private String name;private int age;@Ignoreprivate int sessionId;// Standard getters & setters generated by your IDE…public String getName() { return name; }public void setName(String name) { this.name = name; }public int getAge() { return age; }public void setAge(int age) { this.age = age; }public int getSessionId() { return sessionId; }public void setSessionId(int sessionId) { this.sessionId = sessionId; }
}
注意 所有属性修饰符可以为private
、public
, protected
,一般使用private
,提供setter/getter方法供外部访问。支持定义普通方法。
字段类型
- 基本类型:Realm支持
boolean
,byte
,short
,int
,long
,float
,double
,String
,Date
andbyte[]
的字段类型,其中整形变量byte
,short
,int
,long
在Realm会转换为long
; - 继承
RealmObject
的类型 - List只能使用
RealmList<? extends RealmObject>
- 包装类型:
Boolean
,Byte
,Short
,Integer
,Long
,Float
andDouble
更详细的字段描述可参考官网
修饰符
@primarykey
:主键,一个模型中只能由一个主键@Required
:表示该字段非空@Ignore
:表示忽略该字段,添加 @Ignore 标签后,存储数据时会忽略该字段@Index
:添加搜索索引,为字段添加 @Index 标签,插入速度变慢,查询速度变快,支持索引 String、byte、short、int、long、boolean 和 Date字段
事务
在Realm中事务有两种,同步和异步事务,共有三种开启方式
1. 手动开启事务
Realm realm = Reaml.getDefaultInstance();
//开启事务
realm.beginTransaction();
//创建被Realm管理的实例对象,该对象的所有变更都会被直接应用到Realm数据源中
User user = reaml.createObject(User.calss);
//更改数据
user.setUserName("tudou");
//提交事务:所有的修改数据相关的操作只有在执行事务提交之后,才会被写入到数据库
realm.commitTransaction();
//取消事务:取消事务后,所有对数据 的修改都会被取消
realm.cancelTransaction();
2. 同步事务执行块
//这种方式会自动开启事务,提交事务;并在发生错误时取消事务
realm.executeTransaction(new Realm.Transaction(){@Overridepublic void execute(Realm realm){User user = reaml.createObject(User.calss);user.setUserName("tudou");}
});
3. 异步事务执行块
//使用异步事务,Realm会在后台线程中进行写入操作,并在事务完成时将结构返回调用线程;
//OnSuccess和OnError不是必须的,重载函数的会在事务成功或者失败时在调用线程执行。
RealmAsyncTask asyncTask = realm.executeTransactionAsync(new Realm.Transaction(){@Overridepublic void execute(Realm realm){User user = reaml.createObject(User.calss);user.setUserName("tudou");}
}, new Realm.Transaction.OnSuccess(){@Overridepublic void onSuccess(Realm realm){//事务执行成功时回调}
},new Realm.Transaction.OnError(){@Overridepublic void onError(Realm realm){//事务执行失败时回调}
});
//当你退出Activity或者Fragment时,要记得使用RealmAsyncTask取消异步事务;
//如果你在回调函数中更新 UI,那么忘记取消异步事务可能会造成你的应用崩溃
if(asyncTask != null && !asyncTask.isCancelled()){asyncTask.cancel();
}
注意
在UI和后台线程同时开启创建write的事务,可能会导致ANR错误。为了避免该问题,可以使用executeTransactionAsync来实现。
数据库操作-增
1. copyToRealm()
/createObject()
获取自动更新的Realm模型
复制对象到Realm
User user = new User("John");
user.setEmail("tudou@gmail.com");
// Copy the object to Realm. Any further changes must happen on realmUser
mRealm.beginTransaction();
mRealm.copyToRealm(user);
mRealm.commitTransaction();
注意: copyToRealm()
和copyToRealmOrUpdate
的区别:当Model中存在主键的时候,推荐使用copyToRealmOrUpdate
方法插入数据。如果对象存在,就更新该对象;反之,它会创建一个新的对象。若该Model没有主键,使用copyToRealm
方法,否则将抛出异常。
获取自动更新的模型
realm.beginTransaction();
User user = realm.createObject(User.class); // Create a new object
user.setName("John");
user.setEmail("john@corporation.com");
realm.commitTransaction();
2. inset()
或者 inserOrUpdate()
如果要插入的是多个数据,比如List,则使用insert()
List<User> users = Arrays.asList(new User("John"), new User("Jane"));realm.beginTransaction();
realm.insert(users);
realm.commitTransaction();
3. createObjectFromJson()
Realm支持从Json文件中创建模型;需要两者对应
//假如Json文件格式如下:
{"musicId": "7","name": "Nostalgic Piano",
}
//则可以创建一个模型类
public class MusicModel extends RealmObject{private String musicId;private String name;//省略了setter/getter方法
}
realm.beginTransaction();
realm.createObjectFromJson(MusicModel.class, musicSourceJson);//musicSourceJson为json文件的字符串。如果json文件中有几层,直接使用最外层即可。
realm.commitTransaction();
数据库操作-查
1. realm.where(User.class)
该方法返回一个RealmQuery<User>
对象,大致意思就是得到一张表,然后在表中查询
2. 条件过滤
//所有类型的字段共有的方法
equalTo("name", "John");//第一个参数为字段名,肯定为String,第二个参数为字段的值
notEqualTo();
in(); // 比如:想找名字是否在集合中in("name", new String[]{"Jill", "William", "Trillian"})//整形字段
between (includes both end points, i.e., it is a bounded interval);
greaterThan();
lessThan();
greaterThanOrEqualTo();
lessThanOrEqualTo();//String字段
contains();
beginsWith();
endsWith();
like();//RealmList,String等
isEmpty();
isNotEmpty();
//如果一个字段没有使用 @required 修饰,那么它的值可以为null;可以检查他的值是否为null
isNull();
isNotNull()
3. 逻辑判断
or();//使用or()的使用要配合beginGroup()--->endGroup()使用
and();//默认支持的
not();
RealmResults<User> r = realm.where(User.class).greaterThan("age", 10) // implicit AND.beginGroup().equalTo("name", "Peter").or().contains("name", "Jo").endGroup().findAll();
4. findXxxx()
上几步操作返回的是RealmQuery<User>
对象,调用该对象的findXxx()
返回查询的结果,一个RealmResults<User>
对象:
findAll();//查找出所有满足条件的记录,返回一个RealmResults<> set
findFirst();//查找出满足条件的第一个结果,RealmQuery<User>对象
findAllAsync();//异步查找结果
5. 其他用法
还可以支持对查询结果进行sort()等多种操作,设置监听等,更多请参考官网。
数据库操作-删
删除操作也是需要在事务中进行的。
1. 使用deleteFromRealm()
//先查找到数据,然后再删除
final RealmResults<User> userList = mRealm.where(User.class).findAll();
mRealm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { userList.get(0).deleteFromRealm(); }
});
2. 使用 deleteFromRealm(int index)
mRealm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { userList.deleteFromRealm(0); }
});
3. 其他方法
userList.deleteFirstFromRealm(); //删除user表的第一条数据
userList.deleteLastFromRealm();//删除user表的最后一条数据
results.deleteAllFromRealm();//删除user表的全部数据
mRealm.delete(MusicModel.class); //直接删除一张表
数据库操作-改
修改操作也是需要在事务中进行的。先查找到数据,然后由于模型是可以自动更新的,直接调用setter方法就可以更改数据了。
mRealm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { //先查找后得到User对象 User user = mRealm.where(User.class).findFirst(); user.setAge(26); }
});
数据库的迁移
当数据库新增了模型或者模型中的字段新增、删除时要进行数据库的迁移。一般情况下,是在刚启动APP的时候,磁盘中已经存在一个Realm数据库了,这个时候就需要进行数据库的迁移。所以数据库的迁移动作一般在application中的onCreate()
有两个步骤:
1. 写一个类继承RealmMigration
,重写migrate()
在migrate()
完成数据库的迁移定义
public class MyMigration implements RealmMigration {@Overridepublic void migrate(DynamicRealm realm, long oldVersion, long newVersion) {// DynamicRealm exposes an editable schemaRealmSchema schema = realm.getSchema();// Migrate to version 1: Add a new class.// Example:// public Person extends RealmObject {// private String name;// private int age;// // getters and setters left out for brevity// }if (oldVersion == 0) {schema.create("Person").addField("name", String.class).addField("age", int.class);oldVersion++;}// Migrate to version 2: Add a primary key + object references// Example:// public Person extends RealmObject {// private String name;// @PrimaryKey// private int age;// private Dog favoriteDog;// private RealmList<Dog> dogs;// // getters and setters left out for brevity// }if (oldVersion == 1) {schema.get("Person").addField("id", long.class, FieldAttribute.PRIMARY_KEY).addRealmObjectField("favoriteDog", schema.get("Dog")).addRealmListField("dogs", schema.get("Dog"));oldVersion++;}}
}
2. 设置配置信息,并让Realm执行数据迁移动作
RealmConfiguration config = new RealmConfiguration.Builder().schemaVersion(2) // Must be bumped when the schema changes.migration(new MyMigration()) // Migration to run instead of throwing an exception.build();// 为Realm设置最新的配置
Realm.setDefaultConfiguration(conf);
// 告诉Realm数据需要迁移了try {Realm.migrateRealm(conf);} catch (FileNotFoundException e) {e.printStackTrace();}
总结:
使用Realm数据库的步骤:1,2,3,4,5。
- 在项目中配置
- 初始化Realm并配置Realm、获取Realm的实例。
- 对数据库进行增、删、改、查等操作。
- 如果磁盘中已经有数据库了,在初始化后需要对数据库进行迁移
- 在不使用时,需要关闭数据库连接。
- 一般可以写一个帮助类来辅助完成数据库的相关操作。
参考
Realm for Android 使用入门
【Android】Realm详解
Realm数据库的使用相关推荐
- Realm数据库拾遗
支持数据库加密 // 产生随机密钥 NSMutableData *key = [NSMutableData dataWithLength:64]; SecRandomCopyBytes(kSecRan ...
- Realm数据库存储 使用详解
文章目录 一 Realm 框架 概念介绍 开发辅助工具 二 Realm 使用教程 1 简单的数据操作 创建数据模型 使用RLMRealm对象保存指定模型 使用RLMRealm对象 更新指定模型 使用R ...
- Realm数据库版本迁移
当你和数据库打交道的时候,你需要改变数据模型(Model),但是因为Realm中的数据模型被定义为标准的Objective-C interfaces,要改变模型,就像改变其他Objective-C i ...
- ios realm 文件_iOS Realm数据库使用
Realm 是 SQLite 和 Core Data 的替代者,得益于其零拷贝的设计,Realm 比任何 ORM 都要快很多. Objective‑C版本的 Realm 能够让您以一种安全.耐用以及迅 ...
- Android Realm数据库
In this tutorial, we'll be discussing the basics of Realm Database and implement it in our Android A ...
- android开发收藏功能实现,Android使用Realm数据库如何实现App中的收藏功能
Android使用Realm数据库如何实现App中的收藏功能 发布时间:2021-05-07 11:20:34 来源:亿速云 阅读:63 作者:小新 这篇文章主要介绍了Android使用Realm数据 ...
- android收藏功能demo,Android使用Realm数据库实现App中的收藏功能(代码详解)
前 言 App数据持久化功能是每个App必不可少的功能,而Android最常用的数据持久化方式主要有以下的五种方式: 使用SharedPreferences存储数据: 文件存储数据: SQLite数据 ...
- Android Realm数据库完美解析
转自 http://blog.csdn.net/fesdgasdgasdg/article/details/51897212 demo http://download.csdn.net/detai ...
- 如何在Android中使用Realm数据库
我们都知道使用SQLite的本地数据库,它在Android 开发中用于内部存储器存储,主要存储本地数据,如联系人,电话详细信息等.现在我发现一个比SQLite更轻的数据库,被称为Realm数据库,我想 ...
最新文章
- 【复习】服务器主板——Leez P710
- SUBMIT - selscreen_parameters
- 在eclipse中查看Android源代码
- iframe标签 父子页面传值
- Vue Nginx反向代理配置 解决生产环境跨域
- 蓝桥杯 ALGO-69 算法训练 字符串逆序
- C++进阶教程之信号处理
- springboot毕设项目银行助学贷款管理系统0o571(java+VUE+Mybatis+Maven+Mysql)
- iOS/Android开发人脸识别SDK列表
- mac OSX安装VTK
- 手机里实现图片文字识别的实用方法
- 非常不错的window磁盘清理工具C盘清理
- 李开复:未曾公布的乔布斯故事
- 【独家分享】QQ常见网络骗术***战
- ‘lengths‘ argument should be a 1D CPU int64 tensor, but got 1D cuda:0 Long tensor
- python的pyecharts(群图乱舞)可视化神器
- excel 关联数据
- 李建忠设计模式之总结
- AL32UTF8/UTF8(Unicode)数据库字符集含义 (文档 ID 1946289.1)
- Android Build类获取设备信息
热门文章
- Ipad购买和使用教程(1)
- Procreate iPad绘画教程
- 互联网文艺复兴者——互联网之父Vinton G. Cerf
- php select只有一条_读取数据库如何只取出一条数据????请赐教!
- 营收净利同比上涨,甲骨文回“血”了吗??
- Atmega的TWI通信,包含模拟IIC,硬件查询方式,以及硬件方式收发程序
- 考试自动评分系统C语言改错,基于XML结构的C语言考试的自动评分系统.doc
- 人民币转换---java代码实现
- php留言板在数据库没有ip,关于php:如何连接数据库(未知主机,无IP)
- 计算机语言学笔记(二)现代汉语切分研究