2017-02-15 49 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