从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异步查询。

不支持自增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/


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

Realm Java的学习、应用、总结的更多相关文章

  1. Java的学习之路

    记事本 EditPlus eclipse Java的学习软件,已经系统性学习Java有一段时间了,接下来我想讲一下我在Java学习用到的软件. 1.第一个软件:记事本 记事本是Java学习中最基础的编 ...

  2. Java多线程学习笔记

    进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...

  3. Java Web 学习路线

    实际上,如果时间安排合理的话,大概需要六个月左右,有些基础好,自学能力强的朋友,甚至在四个月左右就开始找工作了.大三的时候,我萌生了放弃本专业的念头,断断续续学 Java Web 累计一年半左右,总算 ...

  4. Java基础学习-- 继承 的简单总结

    代码参考:Java基础学习小记--多态 为什么要引入继承? 还是做一个媒体库,里面可以放CD,可以放DVD.如果把CD和DVD做成两个没有联系的类的话,那么在管理这个媒体库的时候,要单独做一个添加CD ...

  5. 20145213《Java程序设计学习笔记》第六周学习总结

    20145213<Java程序设计学习笔记>第六周学习总结 说在前面的话 上篇博客中娄老师指出我因为数据结构基础薄弱,才导致对第九章内容浅尝遏止地认知.在这里我还要自我批评一下,其实我事后 ...

  6. [原创]java WEB学习笔记95:Hibernate 目录

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  7. Java多线程学习(转载)

    Java多线程学习(转载) 时间:2015-03-14 13:53:14      阅读:137413      评论:4      收藏:3      [点我收藏+] 转载 :http://blog ...

  8. java基础学习总结——java环境变量配置

    前言 学习java的第一步就要搭建java的学习环境,首先是要安装JDK,JDK安装好之后,还需要在电脑上配置"JAVA_HOME”."path”."classpath& ...

  9. Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问

    本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这 ...

随机推荐

  1. R语言Data Frame数据框常用操作

    Data Frame一般被翻译为数据框,感觉就像是R中的表,由行和列组成,与Matrix不同的是,每个列可以是不同的数据类型,而Matrix是必须相同的. Data Frame每一列有列名,每一行也可 ...

  2. FFMPEG ./configure 参数及意义

    FFMPEG版本:2.6.2,编译环境:ubuntu 14.4. 不同版本的FFMPEG参数可能不同,可在FFMPEG目录下使用以下命令查看 ./configure --help --help pri ...

  3. 成为 Linux 终端高手的七种武器 之七 条件执行&&

    7.条件执行 Bash 也可以连续执行两条命令。 第二条命令仅在第一条命令成功执行后才会开始执行。如要如此,你可以通过键入“&&”,也就是两个“&”字符进行分隔,在同一行输入两 ...

  4. Linux下ejabberd开机自启(CentOS)

    废话少说,Linux下开机自启动Ejabberd步骤如下: 1.从ejabberd安装目录的bin目录拷贝ejabberd.init到/etc/init.d/ejabberd下 [root@imser ...

  5. WCF自定义Header

    MiscWebSrvcInfClient client = new MiscWebSrvcInfClient("MiscWSBeanPort", ConfigurationMana ...

  6. javaScript事件(五)事件类型之鼠标事件

    一.事件 二.事件流 以上内容见:javaScript事件(一)事件流 三.事件处理程序 四.IE事件处理程序 以上内容见javaScript事件(二)事件处理程序 五.事件对象 以上内容见javaS ...

  7. 广州APP开发外包公司哪家比较好?广州达到信息技术有限公司技术到底怎么样?

        广州APP开发公司哪家比较好,广州手机APP软件开发公司广州达到信息表示:用户的刚性需求是公司使用手机APP软件盈利的根本前提和基础,所以开发一款手机APP应用时必须从客户的角度来思考.因此公 ...

  8. Windows环境下Android Studio v1.0安装教程

    Windows环境下Android Studio v1.0安装教程 准备工具 JDK安装包. 要求:JDK 7以及以上版本. Android Studio安装文件. Windows: exe(包含SD ...

  9. 第一天接触Orchard

    第一天接触Orchard 为什么要研究Orchard 呢? 楼主是因为要研究下最新的ASP.NET技术, Orchard 用的人多,历史也比较久,算是老牌了 再就是中文资料比较多,Orchard 有中 ...

  10. U3D的飞船太空射击例子中,使用coroutine

    coroutine 协同程序与线程差不多,也就是一条执行序列,拥有自己独立的栈,局部变量和指令指针,同时又与其它协同程序共享全局变量和其它大部分东西.线程与协同程序的主要区别在于,一个具有多线程的程序 ...