Realm數(shù)據(jù)庫使用及踩坑(Android-Kotlin)

前言

最近公司新開發(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)建方式有兩種:

    1. 繼承RealmObject

      繼承RealmObject

    2. 實現(xiàn)RealmModel并添加@RealmClass修飾符

      實現(xiàn)Realm Model并添加@RealmClass

    • 支持的屬性

    boolean, byte, short,int,long,float, double,String, Datebyte[], RealmObject, RealmList<? extends RealmObject>

    還支持Boolean, Byte, Short, Integer, Long, FloatDouble

    Tip:整數(shù)類型 short、intlong 都被映射到 Realm 內的相同類型(實際上為 long

    • @PrimaryKey——表示該字段是主鍵

    字段類型必須是字符串(String)或整數(shù)(byte,short,intlong)以及它們的包裝類型(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,longbooleanDate字段。

結合RxJava使用

RxJava是一個在 Java VM 上使用可觀測的序列來組成異步的、基于事件的程序的庫。

Realm包含了對RxJava的原生支持。


Rxjava調用

這里使用asFlowable輕松轉換成RxJava中的Flowable對象,之后可以使用RxJava中的特性,流式編程,使代碼更簡潔,邏輯更清晰。

結合Kotlin使用

Realm完全兼容Kotlin語言,但有些地方需要注意:

  • Model需要時開放的(open
  • 很多RealmApi引用了Java類。你必須在編譯一欄中添加 org.jetbrains.kotlin:kotlin-reflect:$kotlin_version。

踩坑指南

  1. 使用Gson作為Json解析框架的時候,繼承RealmObject的類序列化和反序列化的時候需排除RealmObject中的屬性,否則將因為類RealmObject涉及父子輪調,導致死循環(huán)

    解決方法:使用ExclusionStrategy(排除策略)實現(xiàn)對類或者域的序列化排除

使用ExclusionStrategy(排除策略)實現(xiàn)對類或者域的序列化排除
  1. Realm數(shù)據(jù)自動更新。Realm查找到數(shù)據(jù)后如果數(shù)據(jù)發(fā)生了改變,會直接修改我們查找到的對象中的數(shù)據(jù),但在項目的開發(fā)過程中會導致原生與H5之間不斷的進行無效的交互。

    解決方法:使用firstElement實現(xiàn)只取一次數(shù)據(jù)。

使用firstElement實現(xiàn)只取一次數(shù)據(jù)
  1. 在獲取到Realm實例的時候注意Realm.getDefaultInstance()這個方法,每調用一次這個方法會在當前線程中創(chuàng)建一個新的Realm對象,導致內存占用過大。

解決方法:使用RealmManager管理當前Realm對象,保證一個線程中只存在一個Realm對象。

使用RealmManager管理當前Realm對象
使用RealmManager管理當前Realm對象
使用RealmManager管理當前Realm對象

總結

Realm主要有兩個優(yōu)點:

  • 對象就是表,屬性就是字段,不需要額外的設置(相比GreenDao更簡單)。
  • 相比其他移動端數(shù)據(jù)庫框架,性能更加卓越,存取速度很快。

Realm也有兩個缺點:

  • 不支持繼承父類對象,所有Realm類都必須繼承RealmObject(或者實現(xiàn)RealmModel接口)
  • realm對象只能在創(chuàng)建的線程使用,不允許跨線程訪問realm對象。
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容