2017-02-15 71 views
2

我考慮境界爲各種原因的數據庫解決方案RealmObjects,但目前正在現在牛軋糖拋出的TransactionTooLargeException大一個取得了它,所以我不得不返工我目前的數據庫架構,基於ActiveAndroid,它有自己的煩人的限制。難點在於Realm不支持繼承(https://github.com/realm/realm-java/issues/761),他們似乎並不急於解決它。相反,他們推薦使用合成而不是繼承,但我無法弄清楚如何使用Gson/Json反序列化工作。組成了繼承與GSON系列化

實施例:

超類:動物,與子類狗和德國牧羊犬

public class Animal { 

    private int numLegs; 

    private boolean hasFur; 
} 

public class Dog extends Animal { 
    private String color; 

    private boolean canDoTricks; 
} 

public class GermanShepherd extends Dog { 

    public boolean isGuardDog; 

    public boolean isAtRiskOfHipDysplasia() 
} 

(對不起,這是一個超級罐頭例子,只是爲了說明)。

現在讓我們來說說這個json的樣子:

{ 
    "numLegs" : 4, 
    "hasFur" : true, 
    "color" : "Black & Brown", 
    "canDoTricks" : true, 
    "isGuardDog" : true, 
    "isAtRiskofHipDysplasia" : false 
} 

現在,我無法修改JSON的,因爲它是一個的給它給我的API。

看着這個答案:https://stackoverflow.com/a/41552457/4560689,它似乎有可能以一種非常冒險的方式做出類似的工作,但答案指出,存在限制,包括序列化會出錯。由於服務器只會以不涉及瘋狂構圖的json格式進行會談,因此會出現問題。

我可以寫一個自定義的Gson解串器/序列化程序來使這項工作?如果是這樣,那會是什麼樣子?我基本上需要能夠爲JSON有效載荷轉換成高達Ñ對象,其中N - 1對象嵌套基礎對象的內部。因爲它看起來像Realm必須使用一些奇怪的界面組成形式,所以我有一個如下的類:

public class GermanShepherd { 
    public Animal animal; 
    public Dog dog; 

    // Generate a bunch of delegate methods here 
} 

我吠叫錯了樹嗎?感覺Realm可能不適用於我想要做的事情,並且繼承被構建到我在多個地方使用的API中,特別是在我想要保留的對象中,因此我必須找出解決方法或使用其他解決方案。 ActiveAndroid(我現在使用的)也是一個不太理想的解決方案,我生病時死於處理死鎖,崩潰,查詢後臺線程,現在會導致崩潰,如果數據太大,無法通過意圖等...與SQLite的所有問題。我願意解決我的主要問題或解決此問題的替代方案。在此先感謝您的幫助!

+1

我是誰寫了你發佈的答案。好吧,有一種方法可以通過創建一個GermanShepard POJO(非realmObject)來解決這個問題,它將按照您喜歡的方式與Gson序列化,並在您的GermanShepard的realmObject和此POJO之間進行某種映射。事實上,這正是PPL爲解決此問題而採取的措施。檢查[this](http://johnpetitto.com/no-more-realm)。如果你想讓我寫一個關於如何做的例子,請告訴我,我會發布一些代碼^^。但我會推薦自定義序列化器,這是一個更好的方法。 – AnixPasBesoin

+0

@AnixPasBesoin,感謝您的回覆!如果可能,我想自定義序列化程序。你有沒有想過我會如何做這項工作?我是否像之前一樣使用Gson將API的響應反序列化爲RealmObject,然後將RealmObject序列化回API所期望的json格式? –

+0

Gson和其他自動序列化器是否對其他人來說很奇怪?就個人而言,我認爲我更喜歡手動序列化/反序列化...一些重複(必須添加新字段到序列化器和反序列化器),但我認爲這是一個很好的抽象層,增加了控制和靈活性 - 更新api不需要更新對象的內部;它是如何與API交流的。 –

回答

3

您應該爲每個新RealmObject類扁平具體類,和你的JSON表示映射到它們。

要保留繼承,您可以通過從彼此繼承接口繼承getter/setter方法模擬。

public interface IAnimal extends RealmModel {  
    int getNumberOfLegs(); 
    void setNumberOfLegs(int legs); 
    boolean getHasFur(); 
    void setHasFur(boolean hasFur); 
} 

public interface IDog extends IAnimal { 
    String getColor(); 
    void setColor(String color); 
    boolean getCanDoTricks(); 
    void setCanDoTricks(); 
} 

public interface IGermanShepherd extends IDog { 
    boolean getIsGuardDog(); 
    void setIsGuardDog(boolean isGuardDog); 
    boolean getIsAtRiskOfHipDysplasia(); 
    void setIsAtRiskOfHipDysplasia(boolean isAtRisk); 
} 

因爲那麼你可以做

public class GermanShepard 
    extends RealmObject 
    implements IGermanShepard { 
     private int numLegs; 
     private boolean hasFur; 
     private String color; 
     private boolean canDoTricks; 
     private boolean isGuardDog; 
     private boolean isAtRiskofHipDysplasia; 

     // inherited getters/setters 
} 

你甚至可以使倉儲類出來的

public abstract class AnimalRepository<T extends IAnimal> { 
    protected Class<T> clazz; 

    public AnimalRepository(Class<T> clazz) { 
     this.clazz = clazz; 
    } 

    public RealmResults<T> findAll(Realm realm) { 
     return realm.where(clazz).findAll(); 
    } 
} 

@Singleton 
public class GermanShepardRepository extends AnimalRepository<GermanShepard> { 
     @Inject 
     public GermanShepardRepository() { 
      super(GermanShepard.class); 
     } 
} 

然後

@Inject 
GermanShepardRepository germanShepardRepository; 

RealmResults<GermanShepard> results = germanShepardRepository.findAll(realm); 

但是,您確實可以將它們合併到一個類中,然後給它一個String type;參數以瞭解它最初的類型。這可能比擁有所有這些GermanShepards更好。

+0

如果我理解正確,GermanShepherd擴展RealmObject並實現RealmModel。這是爲什麼? –

+0

'RealmObject'的聲明實際上是'@RealmClass public abstract class RealmObject implements RealmModel',所以這應該不成問題。這是爲了讓'RealmResults '在動物儲存庫中工作。另外我還沒有實際測試過這個,但我認爲它應該可以工作。 – EpicPandaForce

+0

但它聽起來像是用例[「如果你確實需要多態性,你可以通過一個接口共享RealmObject的域」](https://hackernoon.com/designing-the-schema-of-realm-effectively- and-other-realm-tips -feb76c5b6072#.32hs6ed05) – EpicPandaForce