前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【翻译】Realm , ObjectBox ,还是 Room ,哪个适合你?

【翻译】Realm , ObjectBox ,还是 Room ,哪个适合你?

作者头像
IT自学不成才
发布2019-01-08 10:08:19
3.6K0
发布2019-01-08 10:08:19
举报

【翻译】Realm , ObjectBox ,还是 Room ,哪个适合你?

2017-09-30 by Liuqingwen | Tags: Kotlin Android 翻译 | Hits

一、前言

原文标题:Realm, ObjectBox or Room. Which one is for you? 原文地址:https://notes.devlabs.bg/realm-objectbox-or-room-which-one-is-for-you-3a552234fd6e

二、正文

选择,选择,还是选择。当面对数据存储的时候,安卓开发者有太多的类库可选。不论是处理少量对象,还是构建一个大型的数集,这些工具都能完成使命,等着我们去使用。其中有一些是我们经常打交道的,比如 shared preferences 和 纯 SQL 语句,其他的则需要额外的一些依赖。庆幸的是,我保证,在这里我并不会去讨论如何写一个很长的又合理的查询语句。相反,接下来我将会对这些大联盟玩家进行类比,包括:最新发布的 Room 持久化类库 ,年老健壮的 Realm ,以及鲜为人知的新秀 ObjectBox ,它最近才发布 beta 版本。至于最终的选择权,由你决定,当然到最后你也会非常(或多或少吧)清楚地知道应该选择哪一个。毫无例外,在我们开始进入泰坦大战之前,让我先来给它们作一下介绍。

自从它的理念发布( 2011 年左右,原名 “ TightDB ”)以来 Realm 就自然而然地成为了许多开发者的开发首选。为什么呢?你会这么问。因为简单(几乎完全使用最标准的 Java 对象),速度快(大部分是采用 C++ 编写),并且由于 SQL (因为没有使用它)。无需深入太多细节,你就能轻松地创建一个 Realm 数据库并使用它——甚至还能做的更多。这个库无需太多配置,而且官方文档也能手把手地教会你如何一步一步的完成。

存储数据对象所需要做的第一件事就是建立一个数据模型:

open class Box(
        @PrimaryKey var size: Long = 0,
        var name: String = "",
        @Ignore var tempReference: Int = 0
) : RealmObject()

这里如果你使用 Kotlin 的话,唯一值得注意的是,所有的变量必须都要有默认值。注解和继承于 RealmObject 的必要性,都能很好地解释这些代码(希望如此),那么我们继续下一步。

Realm 使用起来如下面的代码一样,非常简单:

Realm.init(context)
val realm = Realm.getDefaultInstance()
val box = realm.where(Box::class.java).findFirst()
realm.executeTransaction {
    //modifying an existing object
    box.size = 20
    box.name = "John"
    //creating a new object
    val secondBox = realm.createObject(Box::class.java)
    secondBox.size = 30
}

完整的例子在此

注意:基于以数据库为中心的原则,我把多线程的任务交给你了。

注意2:的确,这个 box 的名字就是 John 。

进入房间( Room )!一个最新的,光环最闪耀的谷歌官方类库。 Room 在官方的架构指南中占据着一个中心位置,它提供在 SQLite 上的一个抽象层,允许在充分利用 SQLite 的强大基础上进行流畅地数据库访问开发。它完美地剥离开了 SQL 层,并向开发者展示出清晰、易懂的 Java 语法方法。所以,还记得我保证过没有查询语句吗?但是现在我要写一些查询语句了!不过不要担心, Room 包含的一些安全特性,能够提示你万一出现的那些令人讨厌的错误。

当然,至少在我写这篇文章的时候是这样(或许在很长一段时间之后也是这样), Room 是城里最受欢迎的那个孩子,但是我将会尽量保持对他做一个简短的介绍。

在 Room 中有 3 个主要的组件,都是使用注解来展示说明:

Database :你可以使用这个组件来创建数据库的持有者。这个注解定义了一系列的实体,以及类的相关内容——数据中一系列的数据访问对象( 一些 DAO )。同时它也是底层数据连接访问的枢纽。这个注解标记的类必须是一个抽象类并且继承于 RoomDatabase 。你可以使用 Room.databaseBuilder() 或者 Room.inMemoryDatabaseBuilder()获取到它的一个实例。

Entity :这个组件代表了数据库中一行数据的类。对于各个实体,数据库中的表的创建就是为了存储它们的实例。你必须通过数据库类中的实体数组来引用实体类。

DAO :这个组件代表一个数据访问对象的类或者接口。 DAO 负责定义数据库访问的方法。用 @Database 注解的类必须包含一个抽象的方法,它含有 0 个参数,并返回一个使用 @Dao 注解的类。

下面是上面所提到过的组件的 3 个实现(羞愧地从这篇精彩的文章中复制了过来):

@Entity(tableName = “task”)
data class Task(@ColumnInfo(name = “completed_flag”) var completed: Boolean = false,
@ColumnInfo(name = “task_desciption”) var description: String) {
    @ColumnInfo(name = “id”)
    @PrimaryKey(autoGenerate = true) var id: Long = 0
}
@Dao interface TaskDao {
    @Query(“select * from task”)
    fun getAllTasks(): List<Task>
    @Query(“select * from task where id = :p0”)
    fun findTaskById(id: Long): Task
    @Insert(onConflict = REPLACE)
    fun insertTask(task: Task)
    @Delete
    fun deleteTask(task: Task)
}
@Database(entities = arrayOf(Task::class), version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
    abstract fun taskDao(): TaskDao
}

创建一个数据库并访问它的方法非常简单:

var database = Room.databaseBuilder(context, AppDatabase::class.java,”db”)
            .allowMainThreadQueries().build()

database.taskDao().insertTask(Task(description = “simple!”))

作为最新的成员, ObjectBox 给数据库带来了一大堆功能。但是在如此高的门槛面前,这个崭新的无 SQL 技术库能够和其他的大牌分庭对抗吗?毫无疑问,如果和 Realm 以及 Room 面对面肉搏的话,它必须重拳出击。结果的确如此,它不止一次重锤出击,而是出了一系列的重锤对抗。这里有这个新生库所突出的一些亮点:

速度:如同 Realm , ObjectBox 一样,能够提供卓越的性能,甚至某些时候它能够完全碾压其竞争对手(稍后再谈这个)。

查询生成器:使用 ObjectBox 查询对象和编译时错误检查都非常简单。

数据关联:对象的引用/关联是内建的内部类型,它们都属于原生本地引用。

无需手动数据模式迁移:它能够自动处理新版本对象所新加的、删除的、重命名的属性。

等等,等等

那么实际代码中它是怎样的呢?

它必须有定义的模型,至少目前来说你应该很熟悉了:

@Entity
data class Note(@Id var id: Long = 0, val text: String)

ObjectBox 使用叫做 Boxes (猜一下)的对象来存储并操作数据。只需 2 行代码就能把数据库和操作分离:

确切地说,“数据存储盒子”对象,应该放置在你的 Application 类中:

MyObjectBox.builder().androidContext(App.this).build()

每个“盒子”对应你的数据库中的数据模型。这些盒子作为一个交互点服务于你和你的数据库之间。

var notesBox = boxStore.boxFor(Note::class.java)

一个很重要的细节是:这些盒子类型都是自动生成的,这意味着你所需要担心的事情变得更少。

一旦完成了这些,你就可以准备下一步行动了,这里有一些可用的方法提供给你使用:

notesBox.put(note)
notesBox.remove(note)
notesBox.count()

完整的 Box 类方法列表可以查看它的 Java 文档。这里有一件事需要提醒注意的是名叫 DaoCompat 的兼容层,允许使用像 greenDAO 一样的 API 来操作 ObjectBox 。

  • 比较

到目前为止,所有的类库都做到了差不多相同的事情,有些需要,有些则不需要 SQL 语句。然而,我们更感兴趣的是它们的区别。如下图,我通过 3 种不同的方式分别测试了它们的性能,测试过程使用的是这个开源的性能测试应用程序

realm_objectbox_room_comparison
realm_objectbox_room_comparison
realm_objectbox_room_comparison
realm_objectbox_room_comparison
realm_objectbox_room_comparison
realm_objectbox_room_comparison
realm_objectbox_room_comparison
realm_objectbox_room_comparison
realm_objectbox_room_comparison
realm_objectbox_room_comparison

测试 100k/10k 个元素的性能,以毫秒为单位

非常漂亮而又很有意思的结果,你觉得呢?从这个测试中可以很清晰地看到,大多数情况下 ObjectBox 都能碾压所有其他竞争对手。并且,当然随着元素的数量级的增加,差距变得越来越大!对于一个新成员来说,表现得还行。可以说非常好。

realm_objectbox_room_comparison
realm_objectbox_room_comparison

查询同样看上去是 ObjectBox 的一个强项。测试中采用了字符串和索引,结果不言自明。

那么 apk 的大小又如何呢?这几个类库对我们项目的整体速度影响又有几何?好吧,我们可以使用最新发布的 apk 分析工具来精确地查看一下每一个类库其影响程度如何。

ObjectBox 和 Realm 分别占用空间高达 1-1.5MB3-4MB (这个大小取决于手机的框架),而 Room ,作为一个 SQL 包装工具,仅仅占用了 50KB 的大小。但是为秉承安卓开发者一贯作风,我们还必须针对那烦人的方法数量限制进行一下统计。在这个方法层面上, Room 那谦虚的 300 个方法数 看起来又要再次领跑比赛了。接着是有着 1300 个方法的 ObjectBox 和 2000 个方法的 realm。

明智的是,这几个竞争者都各自提供了一些额外的特性。 Room 提供了 SQLite 所能做的一切,并附加了一些其他的功能。比如迁移机制,而且这完全是可以进行测试的。相反, ObjectBox 甚至都不需要这个,因为它会自动处理大部分情况下的迁移(尽管对于某些改变,它需要额外的信息来明确目标)。 Realm 则装备了最多的令人惊奇的武器,它的这些特性包括自定义配置,加密和更多其他功能(这也是它尺寸比较大的原因之一)。

  • 结论

我们可以看到,不论你选择了哪条路,它都有着自己的长处和短处。如果你需要速度和效率,很明显 ObjectBox 是一个不错的选择。然而,如果你被应用的大小所限制,被那 64k 个方法所限制,同时你也愿意去使用 SQL 语句,那么 Room 是一个很好的解决方案。另一方面,针对 Realm ,可能不是最快的,也不是最小的,但是在它们背后,在经历了超过 7 年的问题反馈检测和改进之后,它给大家提供的是最稳定的、无 bug 的、理智的解决方案。

至于选择哪一个,这取决于你,但是请记住,一个应用程序只要你选择对了就足够了(当然也取决于你的代码,但是那又是另一个话题了)

三、完

作者:Radoslav Yankov 平台:Dev Labs 标签: Android Objectbox Realm Room Comparison

Kotlin Android 翻译


本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-09-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 【翻译】Realm , ObjectBox ,还是 Room ,哪个适合你?
    • 一、前言
      • 二、正文
        • 三、完
        相关产品与服务
        数据库
        云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档