Room,Realm,,ObjectBox 你选择哪个?

面对数据存储的时候,Android开发者有太多的库可以选择了。不管是对象映射还是数据集合,都有相应的工具可用。一些是开箱即用,比如 shared preferences 和 纯 SQL,其他的则需要外部依赖。放心,我这里不会讨论关于写复杂的数据查询语句的事情。相反,我将比较几个一流的库:新发布的Room Persistence Library,有些年生的Realm,以及不太为人所知的ObjectBox,一个最近出了beta版本的库。

最终的选择我留给你自己,但是谁是第一在文章的最后应该大致清晰了。在这之前,我们先一一介绍它们。

Realm 

自从它诞生以来(大概2011,最初叫做“TightDB”),Realm就成为了很多开发者的选择。为什么?简单(几乎是使用标准的Java对象),速度(大部分用C++编写)以及无需写SQL。创建一个Realm数据库很简单,其使用也很简单。这个库只需很少的设置,官网的文档解释的很详细:

首先需要的是一个代表存储对象的model:

 
  1. open class Box (
  2. @PrimaryKey var size: Long = 0, 
  3. var name: String = "", 
  4. @Ignore var tempReference: Int = 0) : RealmObject() {}

唯一值得一提的是如果你使用Kotlin,所有的成员都必须要有默认值。注解和继承RealmObject这都是一看就懂的,所以我们继续。

使用Realm:

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

Full example

Room Persistence Library 

Room是Google最新的也是最亮眼的库,在官方的架构指南中也占据着核心的位置,Room提供了一个SQLite之上的抽象层,使得在充分利用SQLite功能的前提下顺畅的访问数据库。它很好的封装了 SQL,把容易理解的 Java 方法暴露给开发者。还记得我说过没有sql查询?好吧,现在我准备写点查询语句,不过别担心,Room提供了一些安全机制,出现严重的错误会提出警告。

鉴于现在Room已经比较受欢迎,对它的介绍我尽量简短一些。

Room有三个主要的组建,都是用注解来表示:

Database: 你可以用它来创建一个数据库。这个注解定义了Entity的列表,以及数据库中的data access objects(DAO)。同时它也是底层连接数据库的入口。

这个注解类必须为一个继承RoomDatabase的抽象类。你可以使用Room.databaseBuilder() 或者 Room.inMemoryDatabaseBuilder() 来实例化它。

Entity: 这个组建代表数据库中的表。对每一个entity,数据库都创建一张表来持有。你必须在Database类的entity数组中引用entity类。

DAO:这个组建代表Data Access Object类或者接口。DAO负责定义操作数据库的方法。@Database注解的类中必须包括0参数的返回 @Dao类的抽象方法。

下面是实现了所提到的组建代码(无耻的拷贝自 这篇 文章):

 
  1. @Entity(tableName = “task”)
  2. data class Task(@ColumnInfo(name = “completed_flag”) var completed: Boolean = false,
  3.  @ColumnInfo(name = “task_desciption”) var description: String) {
  4.  @ColumnInfo(name = “id”)
  5.  @PrimaryKey(autoGenerate = true) var id: Long = 0
  6. }
  7. @Dao interface TaskDao {
  8.  @Query(“select * from task”)
  9.  fun getAllTasks(): List<Task>
  10. @Query(“select * from task where id = :p0”)
  11.  fun findTaskById(id: Long): Task
  12. @Insert(onConflict = REPLACE)
  13.  fun insertTask(task: Task)
  14. @Delete
  15.  fun deleteTask(task: Task)
  16. }
  17. @Database(entities = arrayOf(Task::class), version = 1, exportSchema = false)
  18. abstract class AppDatabase : RoomDatabase() {
  19. abstract fun taskDao(): TaskDao
  20. }

创建一个数据库以及调用它的方法就如下面这般简单:

 
  1. var database = Room.databaseBuilder(context, AppDatabase::class.java,”db”).allowMainThreadQueries().build()
  2. database.taskDao().insertTask( Task(description = “simple!”) )

ObjectBox 

作为一个最新的成员,ObjectBox为我们带来了很多东西。但是在门槛已经被拉高的情况下,这个新的NoSQL技术能与前面的战场老兵相比吗?如果它想要与 Realm 和 Room 比肩,必须使出一记重锤才行。也的确不只使出了,还不止一记,而是一套。这里是它最典型的亮点:

  • 速度:跟Realm一样,ObjectBox提供了出色的性能,有时还超越了。

  • QueryBuilder:ObjectBox只需要你查询对象,并在编译时检查。

  • Object Relations: Object references / relationships are a built-in type; they are native references

  • 不需要手动迁移 : 升级是完全自动的,不需要关心属性的变化以及命名的变化

  • 更多

那么实际使用是什么样的呢?

model是必须的:

 
  1. @Entity
  2. data class Note (
  3.  @Id var id: Long = 0,
  4.  val text: String
  5. )

ObjectBox通过叫做Boxes的东西来存储对象的数据。要使用ObjectBox来管理数据库,你只需两步:

一个 “Box Store” 对象,在Application 中初始化:

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

以及每一个model对应的“Boxes”。这些box负责与数据库的交互。

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

一个重要的细节是这些Box类型是自动生成的,不需要额外的担心!

好了之后,你就可以开始使用了,下面是一些可以使用的方法:

 
  1. notesBox.put(note)
  2. notesBox.remove(note)
  3. notesBox.count()

要了解Box class的所有方法,请看它的 JavaDoc。这里要注意的是,名为一个 DaoCompat 的兼容层可以让ObjectBox使用类似greenDAO的API。

比较

到目前为止,所有的库几乎都做的是一样的事情,有些要用SQL,有些不。但是能让我们感兴趣的是它们的不同点。下图中,我们使用开源的排名app 测试了三种方式的性能。

这个结果比较有趣,是吧?测试结果清楚的表明,大多数时候,ObjectBox都碾压所有对比。而且随着测试数据的增多,差距就更大了!

查询也是似乎也是ObjectBox的强项之一。测试主要针对索引和字符串,结果显而易见。

那么apk大小呢?这些库分别会给项目带来多少负担呢?我们可以使用最新发布的 apk analyzer来看看它们各自到底有多大。

ObjectBox 和 Realm 分别占用了 1–1.5MB 和 3–4MB(大小取决于手机的架构),而Room,作为一个SQL的封装,只占用了大约50kb。但是作为一个忠实的Android开发者,我们还必须遵守烦人的方法数限制。在这方面,Room似乎再一次领先,只有300个方法。ObjectBox和Realm分别是1300和2000个方法。

功能方面,每个库都提供了自己的额外功能。Room除了提供SQLite能做的所有事情之外,还添加了更多。比如完全可测试的迁移机制。相反ObjectBox并不需要,因为它自己处理了绝大部分迁移(虽然某些改变需要额外的工作)。Realm提供的功能最多,包括自定义配置,加密等等(体积比较大的原因之一)。

总结

可以看到不管你选择哪个都有它的优缺点。如果你追求速度和效率,明显选择ObjectBox。但是如果你受限于app大小,方法数已经接近于64k 的限制,也愿意处理SQL,Room可能是适合你的方案。Realm,虽然不是最快的,也不是最小的,但是有着7年的调试和改进支撑,它可以提供最稳定的,bug最少的,最健全的方案。

 

https://blog.csdn.net/u011897062/article/details/82107709

https://www.jianshu.com/p/24b7ffbbe383

https://www.cnblogs.com/RaphetS/p/5996265.html

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值