1. 程式人生 > >Realm資料庫的那些坑

Realm資料庫的那些坑

Realm算是移動端用的比較多的ORM框架了,當初選擇的時候入了坑,現在只能在這裡慢慢爬了,版本3.1.4。記錄一些存在的坑。

Realm的缺點

id不能自增

解決方案:UUID自動生成,或者每次插入的時候獲取最大的id往上+1.

實體類只能繼承RealmObjet 或者實現RealmModel加@RealmClass註解。

只能直接繼承不能間接繼承。
我的遇到的問題如下,因為所有的資料庫實體類都有一部分同樣的欄位。我就想把這些欄位寫到MyBaseObject基類中,再由基類來繼承ReamObject。實體類直接繼承基類。編譯不過。
Error:(14, 8) 錯誤: Valid model classes must either extend RealmObject or implement RealmModel.

不能參照RealmObject自己實現RealmModel
翻看了一下ReamObject的原始碼發現它是對RealmModel的實現。天真的以為我也可以這麼寫一個基類來繼承。依然編譯不過。一樣的錯誤。
這個RealmModel+註解的方式,簡直是來逗我的

暫無解決方案。老老實實一個一個寫!

查詢的物件帶有RealmProxy物件代理

帶有代理的物件是可以直接進行Realm資料庫操作的。
RealmProxy

實體會多一個ColumnInfo和ProxyState 的物件例項。。ProxyState裡面又包含了該RealmProxy物件。
結構如下:
層級巢狀結構
可以看出這是一種遞迴的儲存方式。至於java為什麼不溢位,因為它的model直接指向了自己的地址。
問題:做遍歷操作會導致ANR和記憶體溢位
解決方案:
1. 類似於這種遞迴的方式如果需要做遍歷操作的話。比如說轉Json或者一些其他的操作的時候不要忘了忽略掉遞迴的物件,否則分分鐘就記憶體溢位ANR了。比如Gson忽略某個欄位

參考
2. 也可以直接把物件copyfromRealm,拿到真正的物件

Realm.getDefaultInstance().copyFromRealm(object);

資料庫版本更新的那些坑

資料庫版本更新介紹

通常來講資料庫更新有三個需要關注的地方。

  • 版本號 .schemaVersion(3)
  • 新版本資訊 .migration()
  • 刪庫更新 .deleteRealmIfMigrationNeeded()
    程式碼如下:
    Realm.init(this);
    RealmConfiguration config = new RealmConfiguration.Builder()
                .schemaVersion(3
) .migration(new Migration()) .deleteRealmIfMigrationNeeded() .build(); Realm.setDefaultConfiguration(config);

版本號就需要每次有做更新schemaVersion往上增加
3 . 4 . 5 …
deleteRealmIfMigrationNeeded() 這句話慎用。

官方說明:

設定這將改變如何處理遷移異常的行為。磁碟上的Realm將被清除並重新建立
加了這句話,如果出現版本號不一致,或者更新出了某些問題。
就會清除掉所有的資料。
migration實現就不做過多介紹了,可以參考這個

坑——資料庫更新後不能回退

如果版本更新做了錯誤的表字段更新,你想要回退。
有兩個解決方案(1) 刪除掉應用重新安裝。(資料會全部丟失)
(2)更新一個版本,把修改還原回去。(工作量大,但是資料不會丟。)

坑——基本型別欄位新增

addField(“xxxfield”,long.class);
一定要用基本型別的class,如long.class,int.class,byte.class 不能用Long.class,Byte.class
這個坑將導致上面的坑。解決方案就看上面看上面吧。

realm對於這種經常用資料庫儲存的應用,真的不好用!!!

坑——Rx流操作

最近想把Realm用Rx流改寫一下,然後又發現了他的坑了。

不支援執行緒切換

在Rx流中我們經常會做執行緒變換操作,然後Realm並不支援其他非建立執行緒中訪問Realm物件。

執行緒切換
也就是說,你在哪個執行緒建立的Realm物件只能在哪個執行緒中使用。mmp,好吧,謝謝你的異常提醒,但我用的不是很爽。

不是很爽解決方案:把Realm物件建立在子執行緒
在IO執行緒中建立一個Realm物件畢竟資料庫操作是個耗時操作。

Realm.getInstance(new RealmConfiguration.Builder().build());

之後就只能在IO執行緒中做操作了。別忘了~~ 2333

Rx操作

嗯,一個Rx流的查詢操作,莫名其妙給我一直髮資料流,相當於無限的查詢。後面才發現是因為我的另外一個操作也是有對資料庫的查詢操作的。 不知道Realm內部怎麼實現。就導致這兩個的subscribe一直重複走。

解決方案:沒有解決方案,建議不要用Rx流。。。。啊啊啊MMP啊 我回不去了!

迎接坑吧!!
realm對於這種經常用資料庫儲存的應用,真的不好用!!!