Java Spring+Mongo+泛型+灵活性

Java Spring+Mongo+泛型+灵活性,java,spring,generics,mongodb,Java,Spring,Generics,Mongodb,当然,以下代码不起作用,因为标记的行无法编译: MyClass { //singleton stuff private static MyClass instance; private MyClass () {} public static MyClass getInstance() { if(instance==null) { instance = new MyClass (); } ret

当然,以下代码不起作用,因为标记的行无法编译:

MyClass {
    //singleton stuff
    private static MyClass instance;
    private MyClass () {}
    public static MyClass getInstance() {
        if(instance==null) {
            instance = new MyClass ();
        }
        return instance;
    }

    // method creating problems
    public NonGenericSuperClassOfGenericClass create(Class<?>... classes) {
        if(someCondition)
             return new GenericClass<classes[0],classes[1]>; // DOES NOT COMPILE
        else
             return new OtherGenericClass<classes[0]>;
    }
}
因此,我实际上不知道create是否会返回

GenericClass<classes[0],classes[1]>

具有不同数量的参数

这是因为我正在使用Spring,并且我计划使用MongoDB,但是在将来我可能需要切换到一些不同的东西,例如Hibernate

GenericClass类类似于:

 GenericClass<PersistetType1, Long> 

其中PersistentType1/2是我需要最终存储在DB中的类,而GenericClass是访问Mongo API的代理。事实上,它看起来像:

  public MongoTemplate getTemplate();
  public void save(T toInsert);
  public List<T> select(Query selectionQuery);
  public T selectById(ID id);
  public WriteResult update(Query selectionQuery, Update updatedAttributes);
  public void delete(T toRemove);
  public void delete(Query selectionQuery);
现在,什么? 从控制器或实体,如果您很挑剔,我需要实例化存储库并调用任何方法。这导致控制器与MongoDB耦合,即它们必须显式实例化此类GenericClass,该类实际上称为MongoRepository,严格依赖于Mongo事实上它是一个具有两个自由度的泛型

所以,我决定创建MyClass,它是隔离控制器的另一个代理。通过这种方式,Controller可以获取MyClass的单个实例,并让它创建相应存储库的新实例。特别是,当somecondition为true时,这意味着我们希望在MongoRepository为false时使用它,可能需要实例化一个Hibernate代理,即hibernatepository。然而,MongoRepository是泛型的,因此它需要某种形式的实例化,我希望将其作为参数传递

不幸的是,泛型是在编译时解析的,所以我想它们对我不起作用


如何解决这个问题?

为了将底层持久性存储与应用程序逻辑解耦,我将使用DAO方法

使用所需的方法(例如保存、更新等)定义DAO的接口,然后为您可能需要的每个持久性提供程序提供一个实现,例如UserAccess可能是您可以实现为HibernateUserAccess和MongouseAccess的接口。在每个实现中,您都会注入适当的模板,例如Mongo或Hibernate,并使用它们来完成持久性操作

您可能遇到的问题是,加载操作将返回一个User实例,这需要在持久性提供者之间有所不同,即JPA注释将不同于MongoDB泄漏抽象所需的Spring数据注释


我可能会通过创建一个用户界面来表示持久性操作的结果,并为每个持久性提供者提供一个实现来解决这个问题。或者返回一个公共模型,您可以根据JPA或Mongo加载的结果构建该模型。

当然这是一个解决方案,但它需要我为每个持久实体实现一个DAO。我不想这样做,因为这需要很多努力,而切换持久性的概率相当低。我宁愿把我的20/25实体与MongoDB结合起来,赌不更换提供商。我会这么做的。更改持久性提供程序并不是经常发生的事情。当然,更新25个实体所涉及的工作无论如何也不是很好。
 GenericClass<PersistentType2, Long>
  public MongoTemplate getTemplate();
  public void save(T toInsert);
  public List<T> select(Query selectionQuery);
  public T selectById(ID id);
  public WriteResult update(Query selectionQuery, Update updatedAttributes);
  public void delete(T toRemove);
  public void delete(Query selectionQuery);