首页 文章

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

提问于
浏览
7

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

  • 节点

  • LeafType1

  • LeafType2

集合是使用父条目中的子节点的dbRefs来存储树状结构 .

我没有问这里:有没有办法使用 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 回答

  • 2

    如果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>{
    ...
    

    And ,如果您在mongodb集合中的文档没有"_class"属性 . 你可以使用Converter

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

  • 6

    在查找实体类时,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") 注释

相关问题