Spring Data Mongodb - 用于收集不同类型的存储库

时间:2014-12-02 09:46:30

标签: java spring mongodb spring-data spring-data-mongodb

我有一个mongo集合,可能包含三种类型的实体,我映射到java类型:

  • 节点
  • LeafType1
  • LeafType2

Collection是使用父条目中子节点的dbRefs来存储树状结构。

我在Spring参考文档中找不到有关主题的任何信息,所以我在这里问:是否有办法使用Repository机制来处理可能包含不同类型对象的集合?

在一个集合中为不同类型声明几个存储库似乎不是一个好主意,因为当查询对象不是预期类型并且为抽象类创建一个所有可能类型继承的似乎没有的情况时,我总是很难处理工作。

说明我的意思:

/**
 * This seems not safe
 */
public interface NodeRepository extends MongoRepository<Node, String> { }
public interface LeafType1Repository extends MongoRepository<LeafType1, String> { }
public interface LeafType2Repository extends MongoRepository<LeafType2, String> { }

/**
 * This doesn't work at all
 */
public interface MyCollectionRepository extends MongoRepository<AbstractMyCollectionNode, String> { }

2 个答案:

答案 0 :(得分:6)

如果Node \ LeafType1 \ LeafType2是AbstractMyCollectionNode的子类,那么事情就很容易了。只需像你写的那样声明存储库:

public interface MyCollectionRepository extends MongoRepository<AbstractMyCollectionNode, String> { }

我们在一个项目中完成了这项工作,并且运作良好。 Spring Data将添加一个名为&#39; _class&#39;到mongodb集合中的文档,以便它可以指出要实例化的类。

存储在一个集合中的文档可能有一些相似之处,也许您可​​以为它们提取一个通用类。

以下是从我们的某个项目中复制的一些代码:

实体:

public abstract class Document {
    private String id;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
    ....

public class WebClipDocument extends Document {
    private String digest;
    ...

存储库:

public interface DocumentDao extends MongoRepository<Document, String>{
...

,如果您在mongodb集合中的文档没有&#34; _class&#34;属性。您可以使用Converter

  

当存储和查询对象时,让MongoConverter实例处理所有Java类型到DBObjects的映射是很方便的。但是,有时您可能希望`MongoConverter完成大部分工作,但允许您有选择地处理特定类型的转换或优化性能。

答案 1 :(得分:2)

Spring数据在查找实体类时使用Repository-Declarations作为入口点(它不直接扫描实体的包)。

所以你需要做的就是声明一个&#34;未使用的&#34;您的子类的存储库接口,就像您提议的那样&#34;不安全&#34;在你的OP:

public interface NodeRepository extends MongoRepository<Node, String> { 
  // all of your repo methods go here
  Node findById(String id);
  Node findFirst100ByNodeType(String nodeType);
  ... etc.
}
public interface LeafType1Repository extends MongoRepository<LeafType1, String> {
  // leave empty
}
public interface LeafType2Repository extends MongoRepository<LeafType2, String> { 
  // leave empty
}

您不必使用其他LeafTypeX存储库,您可以坚持使用NodeRepository来存储和查找LeafType1类型的对象和{ {1}}。但是需要声明其他两个存储库,以便在初始扫描时将LeafType2LeafType1作为实体找到。

PS:当然,这一切都假定您在LeafType2@Document(collection= "nodes")类上有LeafType1个注释