Realm Java的学习、应用、总结

从React Native珠三角沙龙会议了解到Realm这个开源库,然后开始学习、理解和使用Realm。Realm是跨平台、支持多种主流语言,这里主要是对Realm Java结合实际项目的一些情况进行记录。

Realm是什么?

Realm官网:https://realm.io/cn/

Realm,为移动设备而生!替代 SQLite 和 Core Data。为你省下数周的时间和数千行的代码,帮你创造出更棒的用户体验。--Realm官网

从上面官网的定义,我们大概知道它是一个移动端的数据库。想了解更多到官网,在这里不做过长的介绍。

Realm Android的性能

对于Realm Android的性能也是我们比较关注的一个问题,我也是看到Realm的性能比其他数据库要快,所以才去了解以及学习它。下面从官网的三张图片来了解一下它的性能。

  • 插入操作:在同一个事务里,每秒插入100K条记录(越高代表性能越好)


  • 统计操作:每秒能在100K条数据中进行查询后count的次数(越高代表性能越好)


  • 查询操作:在100K中进行一次遍历查询(越高代表性能越好)


Realm不是基于SQLite的ORM,它是基于C++ 存储引擎的。所以,它的速度相当来说比较快的,但是目前它也引发了应用的安装包大小问题。(估计目前他们正在优化这个问题)
详细性能内容查看官方的文档:
https://realm.io/news/realm-for-android/#realm-for-android

为什么选择Realm Java?

目前在开发应用的IM模块使用到数据库ormlite存储数据。每次打开应用切换到消息列表的时候要等一会才加载出来,从会话点聊天列表加载聊天记录(聊天记录上W条)要转转转转转才出来。看到Realm性能写得好像好厉害的样子,所以尝试运用Realm Java。
可能你会问,为什么不选择DBFlow,GreenDAO,ActiveAndroid?
DBFlow在创建数据库的时候,数据库名称和版本号都是使用static final修饰变量,而我的应用数据库设计是每个账号对应一个数据库,所以DBFlow在切换数据库的时候,有点力不从心,最张放弃使用DBFlow。而GreenDAO性能上也不错,但是创建Model和数据库升级挺折腾的,总得来说greenDAO投入成本高。(我比较懒~~),ActiveAndroid没有尝试过,有空可以试一下。

Relam Java(v0.91.0)目前遇到的一些问题

Realm Java集成

Realm Java的GitHub地址:https://github.com/realm/realm-java
个人推荐按照官网文档集成Realm Java。因为我之前按照Github中的文档集成Realm Java没有成功,最后按照官网的就可以了。
如果你的项目有多个Module的话。如下图,则可以在util的Module加入Realm Java就可以了。

Realm 数据库文件大小

这里我测试了一下引入Realm Java后apk大小的变化。如下图,可以看到引入后apk足足大了4M。


没有引入Realm Java
引入Realm Java

备注:以下的代码均运行在子线程,这里没有使用Realm异步查询。

不支持自增ID

在新增数据表的时候,往往定义自增ID,这样做是降低与业务逻辑的耦合。

//ormlite可以定义自增id
@DatabaseField(generatedId = true)
public int _id;
//realm java 不支持自增id,这里我使用了UUID来生成,我也没办法了
//使用我们项目中已经使用到id.
public String _id = UUID.randomUUID().toString();

不支持limit

场景:每次找出符合条件的20记录并返回。
然而,Realm Java没有这样的操作。
这个在github中的issue有人提交了。here
看下面的代码,我找出所有符合条件的记录,然后根据传入的大小将结果截取并返回。(Y的,如果记录上W条的话,不就很坑吗)

realm.beginTransaction();
String [] orderFiled = {"time","_id"};
Sort [] sorts = {Sort.DESCENDING, Sort.DESCENDING};
RealmResults<Message> results = realm.where(Message.class)
    .equalTo("sessionType",  ModelFileds.SESSION_TYPE_MESSAGE_STRANGER)
    .equalTo("sessionId", sessionId)
    .or()
    .equalTo("sessionType", ModelFileds.SESSION_TYPE_MESSAGE_FRIEND)
    .equalTo("sessionId", sessionId)
    .findAllSorted(orderFiled, sorts);
realm.commitTransaction();
return results.subList(0, size);

update操作

场景:找出符合条件的记录,并对某个字段进行值的修改。

  • ormlite使用UpdateBuilder就可以完成这个操作了。
localSqliteHelper = new LocalSqliteHelper(mAccount.getUuid());
UpdateBuilder<MessageModel, Integer> updateBuilder
     = getMessageDao(localSqliteHelper
.getWritableDatabase()).updateBuilder();
updateBuilder.where()
    .eq("sessionId", sessionId).and()
    .eq("sessionType", sessionType).and()
    .eq("sessionSecondId", sessionSecondId).and()
    .eq("sessionSecondType", sessionSecondType).and()
    .eq("isSend", MessageModel.OTHER_TO_ME);
updateBuilder.updateColumnValue("status", 1);
return updateBuilder.update();
  • Realm Java我只能这样写了。(将符合条件的记录遍历赋值,我也无语了)
realm.beginTransaction();
RealmResults<Message> messages = realm.where(Message.class)
        .equalTo("sessionId", sessionId)
        .equalTo("sessionType", sessionType)
        .equalTo("sessionSecondId", sessionSecondId)
        .equalTo("sessionSecondType", sessionSecondType)
        .equalTo("isSend", MessageModel.OTHER_TO_ME)
        .findAll();
for (Message msg : messages)
    msg.status = 1;
realm.copyToRealmOrUpdate(messages);
realm.commitTransaction();

like模糊查询

场景:输入关键字显示匹配关键字的记录。

  • ormlite使用like就可以了。
LocalSqliteHelper localSqliteHelper = null;
try {
    localSqliteHelper = new LocalSqliteHelper(mAccount.getUuid());
    return getProjectDao(localSqliteHelper.getWritableDatabase())
            .queryBuilder().orderBy("update_date", false)
            .where()
            .like("name", "%/" + keyword + "/%").query();
} catch (SQLException e) {
    throw new DBException(e);
} finally {
    if (localSqliteHelper != null) {
        localSqliteHelper.close();
    }
}
  • Realm Java先找出符合条件,然后再判断是否包含关键字。
realm.beginTransaction();
RealmResults<Project> results = realm.where(Project.class)
    .findAllSorted("update_date", Sort.DESCENDING);
realm.commitTransaction();
if(results != null && results.size() > 0){
  for(int i = results.size() -1; i >=0; i--){
      if(!results.get(i).name.contains(keyword)){
          results.remove(i);  
      }
  }
}
return results;

FAQ

更多问题可以看官网的FAQ:
https://realm.io/cn/docs/java/latest/#faq

stetho-realm工具

如果使用Realm Java,推荐结合stetho-realm工具进行使用。stetho-realm可以查看Realm数据,但是这个工具目前还不支持数据操作。

扩展阅读

最后,安利大家认真阅读Realm官网发布的文章。文章有一定的技术含金量的喔~文章都有中文翻译的,你再也不用担心看不懂!
链接:https://realm.io/cn/news/


以前我不太明白大神们说的多看官方文档、多看源码这个学习方法,那时候我总种感觉是他们在忽悠我。以前的我当接触到新的技术时,第一反应是百度,而且非常非常非常讨厌看官方文档(干脆就不看了);现在我总是渴望深入理解它的使用、原理,也慢慢地习惯阅读看官方文档。改变的过程总是不那么容易,需要你的坚持。生活何尝不是需要通过你自己不断地努力去改变呢~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 148,637评论 1 318
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 63,443评论 1 266
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 99,164评论 0 218
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,075评论 0 188
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,080评论 1 266
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,365评论 1 184
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 30,901评论 2 283
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,649评论 0 176
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,122评论 0 223
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,734评论 2 225
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,093评论 1 236
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,548评论 2 222
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,028评论 3 216
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,765评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,291评论 0 178
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,162评论 2 239
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,293评论 2 242

推荐阅读更多精彩内容