繁体   English   中英

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

[英]Spring Data Mongodb - repository for collection with different types

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

  • 节点
  • LeafType1
  • LeafType2

集合是使用父条目中的子节点的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> { }

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

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

我们在一个项目中完成了这项工作,并且运作良好。 Spring Data会将名为'_class'的属性添加到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集合中的文档没有“_class”属性。 你可以使用Converter

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

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

因此,您需要做的就是为您的子类声明一个“未使用的”存储库接口,就像您在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存储和查找LeafType1LeafType2类型的对象。 但是需要声明其他两个存储库,以便在初始扫描发生时将LeafType1LeafType2作为实体找到。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM