前言
最近公司新開發(fā)了個項目,其中使用到了Realm數(shù)據(jù)庫,在此對Realm數(shù)據(jù)庫的使用及踩坑進行下總結。
Realm簡介
Realm 是一個 MVCC (多版本并發(fā)控制)數(shù)據(jù)庫,由Y Combinator公司在2014年7月發(fā)布一款支持運行在手機、平板和可穿戴設備上的嵌入式數(shù)據(jù)庫,目標是取代SQLite。
Realm 本質上是一個嵌入式數(shù)據(jù)庫,他并不是基于SQLite所構建的。它擁有自己的數(shù)據(jù)庫存儲引擎,可以高效且快速地完成數(shù)據(jù)庫的構建操作。和SQLite不同,它允許你在持久層直接和數(shù)據(jù)對象工作。在它之上是一個函數(shù)式風格的查詢api,眾多的努力讓它比傳統(tǒng)的SQLite 操作更快 。
優(yōu)勢
- 易用
Ream 不是在SQLite基礎上的ORM,它有自己的數(shù)據(jù)查詢引擎。并且十分容易使用。 - 快速
由于它是完全重新開始開發(fā)的數(shù)據(jù)庫實現(xiàn),所以它比任何的ORM速度都快很多,甚至比SLite速度都要快。 - 跨平臺
Realm 支持 iOS & OS X (Objective?C & Swift) & Android。我們可以在這些平臺上共享Realm數(shù)據(jù)庫文件,并且上層邏輯可以不用任何改動的情況下實現(xiàn)移植。 - 高級
Ream支持加密,格式化查詢,易于移植,支持JSON,流式api,數(shù)據(jù)變更通知等高級特性 - 可視化
Realm 還提供了一個輕量級的數(shù)據(jù)庫查看工具:Realm Studio,開發(fā)者可以查看數(shù)據(jù)庫當中的內容,執(zhí)行簡單的插入和刪除數(shù)據(jù)的操作。
使用方式
-
添加依賴
在project的build.gradle中
project的build.gradle中在Application的build.gragle中
Application的build.gragle中
Application的build.gragle中 -
初始化Realm
在 Applaction 的 onCreate() 方法中使用 Realm.init() 初始化
在 Applaction 的 onCreate() 方法中初始化
使用圖上配置會創(chuàng)建一個 REALM_NAME.realm 的 Realm 文件,一般來說這個文件位于 data/data/包名/files 目錄下,通過 realm.getPath 來獲得該 Realm 的絕對路徑
-
在Activity中具體使用
在onCreate中打開數(shù)據(jù)庫
在onCreate中打開數(shù)據(jù)庫
在使用完后在 onDestory() 方法中進行關閉
在onDestroy中關閉數(shù)據(jù)庫 -
創(chuàng)建model類
model類的創(chuàng)建方式有兩種:
-
繼承
RealmObject
繼承RealmObject -
實現(xiàn)
RealmModel并添加@RealmClass修飾符
實現(xiàn)Realm Model并添加@RealmClass
- 支持的屬性
boolean,byte,short,int,long,float,double,String,Date和byte[],RealmObject,RealmList<? extends RealmObject>還支持
Boolean,Byte,Short,Integer,Long,Float和DoubleTip:整數(shù)類型
short、int和long都被映射到 Realm 內的相同類型(實際上為long)-
@PrimaryKey——表示該字段是主鍵
字段類型必須是字符串(
String)或整數(shù)(byte,short,int或long)以及它們的包裝類型(Byte,Short,Integer, 或Long)。不可以存在多個主鍵,使用字符串字段作為主鍵意味著字段被索引(注釋@PrimaryKey隱式地設置注釋@Index)。-
@Required——表示該字段非空
在某些情況下,有一些屬性是不能為
null的。使用@Required可用于用于強行要求其屬性不能為空,只能用于Boolean,Byte,Short,Integer,Long,Float,Double,String,byte[]和Date。在其它類型屬性上使用@Required修飾會導致編譯失敗。Tip:基本數(shù)據(jù)類型不需要使用注解
@Required,因為他們本身就不可為空。-
@Ignore——表示忽略該字段
被添加
@Ignore標簽后,存儲數(shù)據(jù)時會忽略該字段。-
@Index——添加搜索索引
為字段添加搜索索引,這樣會使得插入的速度變慢,數(shù)據(jù)量也變得更大。不過在查詢速度將變得更快,建議只在優(yōu)化讀取性能的特定情況時添加索引。支持索引:
String,byte,short,int,long,boolean和Date字段。 -
結合RxJava使用
RxJava是一個在 Java VM 上使用可觀測的序列來組成異步的、基于事件的程序的庫。
Realm包含了對RxJava的原生支持。

這里使用asFlowable輕松轉換成RxJava中的Flowable對象,之后可以使用RxJava中的特性,流式編程,使代碼更簡潔,邏輯更清晰。
結合Kotlin使用
Realm完全兼容Kotlin語言,但有些地方需要注意:
- Model需要時開放的(
open) - 很多RealmApi引用了Java類。你必須在編譯一欄中添加
org.jetbrains.kotlin:kotlin-reflect:$kotlin_version。
踩坑指南
-
使用Gson作為Json解析框架的時候,繼承RealmObject的類序列化和反序列化的時候需排除RealmObject中的屬性,否則將因為類RealmObject涉及父子輪調,導致死循環(huán)
解決方法:使用ExclusionStrategy(排除策略)實現(xiàn)對類或者域的序列化排除

-
Realm數(shù)據(jù)自動更新。Realm查找到數(shù)據(jù)后如果數(shù)據(jù)發(fā)生了改變,會直接修改我們查找到的對象中的數(shù)據(jù),但在項目的開發(fā)過程中會導致原生與H5之間不斷的進行無效的交互。
解決方法:使用firstElement實現(xiàn)只取一次數(shù)據(jù)。

- 在獲取到Realm實例的時候注意
Realm.getDefaultInstance()這個方法,每調用一次這個方法會在當前線程中創(chuàng)建一個新的Realm對象,導致內存占用過大。
解決方法:使用RealmManager管理當前Realm對象,保證一個線程中只存在一個Realm對象。



總結
Realm主要有兩個優(yōu)點:
- 對象就是表,屬性就是字段,不需要額外的設置(相比GreenDao更簡單)。
- 相比其他移動端數(shù)據(jù)庫框架,性能更加卓越,存取速度很快。
Realm也有兩個缺點:
- 不支持繼承父類對象,所有Realm類都必須繼承RealmObject(或者實現(xiàn)RealmModel接口)
- realm對象只能在創(chuàng)建的線程使用,不允許跨線程訪問realm對象。







