文档章节

Realm Java的学习、应用、总结

Common1140
 Common1140
发布于 2016/05/23 16:54
字数 1641
阅读 836
收藏 21

从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/


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

© 著作权归作者所有

共有 人打赏支持
Common1140
粉丝 15
博文 13
码字总数 13069
作品 0
广州
程序员
加载中

评论(3)

pennymei
pennymei
可以试试OneAPM ,他可以为您提供端到端的 Java 应用性能解决方案,支持所有常见的 Java 框架及应用服务器,快速发现系统瓶颈,定位异常根本原因。可以在官网注册试用哦~
Common1140
Common1140

引用来自“巴拉提”的评论

线程问题 没有觉得很蛋疼吗
你是指跨线程问题吗?
巴拉迪维
巴拉迪维
线程问题 没有觉得很蛋疼吗
Java学习---Java简单认识

前言 小编在学习Java方面的基础知识,发现里面有很多是结合之前的语言的特点发展过来的,不同的地方是,Java有它自己的发展和特点。下面小编先简单地做一下总结,结合看过的1-2章的J2SE视频,...

m18633778874
04/01
0
0
Kotlin Weekly 中文周报 —— 102

Kotlin 开发中文周报 使用 Kotlin 高效地开发 Android App(五)完结篇 (jianshu.com) 为爬虫框架构建Selenium模块、DSL模块(Kotlin实现) (jianshu.com) 移动 Realm 到 Kotlin – Blue Apron...

DoubleThunder
07/16
0
0
用大白话告诉你啥是Java开发

Java,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台的总称。用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台、动态的Web、Internet计算。从此...

远方Java
06/14
0
0
Shiro学习(一)之理论知识篇

一:Shiro简介 Apache Shiro 是 Java 的一个安全框架。功能强大,使用简单的Java安全框架,它为开发人员提供一个直观而全面的认证,授权,加密及会话管理的解决方案。 Authentication:身份认...

uug
09/09
0
0
为什么Python成了开发AI的主流语言?Java系列、Ruby等编程语言不行吗?

导读 说道开发AI的语言,很多人说,不是Python吗?没错,Python是可以开发AI,但是不知道你们有没有想过,真的就只有Python才可以开发AI吗? 其实,像Java、Ruby也是开发AI很好的选择,但是为...

柯西带你学编程
05/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

ERC1155实践|区块链游戏的平行宇宙和为此而生的Enjin钱包

1 摘要 恩金(Enjin)花了大半年的时间一直在完善ERC-1155这个通证协议,毫不夸张地说,该标准是现有以太坊上最适用于游戏资产的通证标准,将主流游戏中道具涉及到的一切操作经过高度抽象之后...

HiBlock
20分钟前
0
0
Oracle发布开源的轻量级 Java 微服务框架 Helidon

近日,Oracle推出了一个新的开源框架Helidon,该项目是一个用于创建基于微服务的应用程序的Java库集合。和Payara Micro、Thorntail(之前的WildFly Swarm)、OpenLiberty、TomEE等项目一样,...

关注公众号_搜云库_每天更新
26分钟前
0
0
启动线程以及安全终止线程

启动 使用start()方法可以启动线程。 start()方法的含义是告知线程规划器线程已初始化完毕,可以分给这个线程时间片了(执行run()方法)。 安全终止线程 示例代码 import java.util.concurr...

karma123
33分钟前
1
0
Python+OpenCV 图像风格迁移(模仿名画)

现在很多人都喜欢拍照(自拍)。有限的滤镜和装饰玩多了也会腻,所以就有 APP 提供了模仿名画风格的功能,比如 prisma、versa 等,可以把你的照片变成 梵高、毕加索、蒙克 等大师的风格。 这...

crossin
37分钟前
1
0
karabiner json语法

karabiner json语法 to_if_alone 如果同时制定了to, 那么to对应的key必须是非可见字符,例如control,shift或者command, 为什么呢? If to events are specified, to events are released befo...

黄威
38分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部