文章目录

  • 写在前面
  • 简单使用
    • 几个概念
      • 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中的一个类)表示数据库中的一张表,模型中的字段表示表中的列
  • 模型需要继承RealmObject类
  • 模型实时、自动更新(需要获得当前线程的looper,在主线程中是满足的);操作模型就相当于直接操作数据库中底层数据
2. 事务
  • 所有会使数据发生变化 的操作必须在事务中进行。如:增、删、改
  • 事务分为同步事务和异步事务两种
3. 引用计数
  • Realm实例使用引用计数的方式
  • 生成的Realm实例在使用完后需要手动close。
4. 数据库的迁移

在Realm中如果增加、删除了模型或者模型的字段,需要进行数据库的迁移。这个概念类似于数据库的升级。

添加配置文件

  1. 在project的build.gradle文件中调加依赖
buildscript {repositories {jcenter()}dependencies {classpath "io.realm:realm-gradle-plugin:5.12.0"}
}
  1. 在app下的build.gradle文件顶部添加对应的插件支持
apply plugin: 'realm-android'

初始化Realm并配置Realm

1. 在application的onCreate()中使用Realm.init()初始化
2. 在application的onCreate()中对Realm进行相关的配置

配置不是必须的,如果不配置,会使用默认配置;但是如果有数据库的迁移,那么是需要配置数据库的。

  1. 使用默认配置

有两种方式可以使用默认配置:

//方式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

  1. 自定义配置
// 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; }
}

注意 所有属性修饰符可以为privatepublic, protected ,一般使用private,提供setter/getter方法供外部访问。支持定义普通方法。

字段类型
  • 基本类型:Realm支持 boolean, byte, short, int, long, float, double, String, Date and byte[]的字段类型,其中整形变量byte, short, int, long在Realm会转换为long
  • 继承RealmObject 的类型
  • List只能使用RealmList<? extends RealmObject>
  • 包装类型:Boolean, Byte, Short, Integer, Long, Float and Double
    更详细的字段描述可参考官网
修饰符
  • @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。

  1. 在项目中配置
  2. 初始化Realm并配置Realm、获取Realm的实例。
  3. 对数据库进行增、删、改、查等操作。
  4. 如果磁盘中已经有数据库了,在初始化后需要对数据库进行迁移
  5. 在不使用时,需要关闭数据库连接。
  6. 一般可以写一个帮助类来辅助完成数据库的相关操作。

参考

Realm for Android 使用入门
【Android】Realm详解

Realm数据库的使用相关推荐

  1. Realm数据库拾遗

    支持数据库加密 // 产生随机密钥 NSMutableData *key = [NSMutableData dataWithLength:64]; SecRandomCopyBytes(kSecRan ...

  2. Realm数据库存储 使用详解

    文章目录 一 Realm 框架 概念介绍 开发辅助工具 二 Realm 使用教程 1 简单的数据操作 创建数据模型 使用RLMRealm对象保存指定模型 使用RLMRealm对象 更新指定模型 使用R ...

  3. Realm数据库版本迁移

    当你和数据库打交道的时候,你需要改变数据模型(Model),但是因为Realm中的数据模型被定义为标准的Objective-C interfaces,要改变模型,就像改变其他Objective-C i ...

  4. ios realm 文件_iOS Realm数据库使用

    Realm 是 SQLite 和 Core Data 的替代者,得益于其零拷贝的设计,Realm 比任何 ORM 都要快很多. Objective‑C版本的 Realm 能够让您以一种安全.耐用以及迅 ...

  5. Android Realm数据库

    In this tutorial, we'll be discussing the basics of Realm Database and implement it in our Android A ...

  6. android开发收藏功能实现,Android使用Realm数据库如何实现App中的收藏功能

    Android使用Realm数据库如何实现App中的收藏功能 发布时间:2021-05-07 11:20:34 来源:亿速云 阅读:63 作者:小新 这篇文章主要介绍了Android使用Realm数据 ...

  7. android收藏功能demo,Android使用Realm数据库实现App中的收藏功能(代码详解)

    前 言 App数据持久化功能是每个App必不可少的功能,而Android最常用的数据持久化方式主要有以下的五种方式: 使用SharedPreferences存储数据: 文件存储数据: SQLite数据 ...

  8. Android Realm数据库完美解析

    转自   http://blog.csdn.net/fesdgasdgasdg/article/details/51897212 demo http://download.csdn.net/detai ...

  9. 如何在Android中使用Realm数据库

    我们都知道使用SQLite的本地数据库,它在Android 开发中用于内部存储器存储,主要存储本地数据,如联系人,电话详细信息等.现在我发现一个比SQLite更轻的数据库,被称为Realm数据库,我想 ...

最新文章

  1. 【复习】服务器主板——Leez P710
  2. SUBMIT - selscreen_parameters
  3. 在eclipse中查看Android源代码
  4. iframe标签 父子页面传值
  5. Vue Nginx反向代理配置 解决生产环境跨域
  6. 蓝桥杯 ALGO-69 算法训练 字符串逆序
  7. C++进阶教程之信号处理
  8. springboot毕设项目银行助学贷款管理系统0o571(java+VUE+Mybatis+Maven+Mysql)
  9. iOS/Android开发人脸识别SDK列表
  10. mac OSX安装VTK
  11. 手机里实现图片文字识别的实用方法
  12. 非常不错的window磁盘清理工具C盘清理
  13. 李开复:未曾公布的乔布斯故事
  14. 【独家分享】QQ常见网络骗术***战
  15. ‘lengths‘ argument should be a 1D CPU int64 tensor, but got 1D cuda:0 Long tensor
  16. python的pyecharts(群图乱舞)可视化神器
  17. excel 关联数据
  18. 李建忠设计模式之总结
  19. AL32UTF8/UTF8(Unicode)数据库字符集含义 (文档 ID 1946289.1)
  20. Android Build类获取设备信息

热门文章

  1. Ipad购买和使用教程(1)
  2. Procreate iPad绘画教程
  3. 互联网文艺复兴者——互联网之父Vinton G. Cerf
  4. php select只有一条_读取数据库如何只取出一条数据????请赐教!
  5. 营收净利同比上涨,甲骨文回“血”了吗??
  6. Atmega的TWI通信,包含模拟IIC,硬件查询方式,以及硬件方式收发程序
  7. 考试自动评分系统C语言改错,基于XML结构的C语言考试的自动评分系统.doc
  8. 人民币转换---java代码实现
  9. php留言板在数据库没有ip,关于php:如何连接数据库(未知主机,无IP)
  10. 计算机语言学笔记(二)现代汉语切分研究