Morphia和MongoDB:不断发展的文档结构

本文探讨了如何使用Morphia处理数据库架构的变化,如废弃字段、仅支持旧字段和用嵌入式对象替换字段。通过@AlsoLoad、@NotSaved和@PostLoad等注解,可以在不破坏现有数据的情况下实现代码与文档结构的同步更新。
摘要由CSDN通过智能技术生成
上一篇有关Morphia的文章中 ,我介绍了一些典型用法,并提到了一些已知问题的警告和解决方法。 我展示了使用Morphia多么容易,以及它与Java世界的交互方式。

为了跟进该帖子,我将讨论如何处理一些现实生活中的需求:处理更改的架构并自定义映射以处理诸如只读字段之类的事情,并用复杂的对象替换简单的字段。

变更架构

几乎所有在开发领域中使用过数据库的人都知道,模式一直在发展。 不推荐使用或完全删除字段,废弃表,添加新字段等等。

尽管通过使用像MongoDB这样的无模式数据存储可以避免很多麻烦,但有时我们仍然需要对更改进行特殊处理,就Morphia而言,我们本质上已经定义了模式,因此我们必须找到处理方法。这个。 最好的一点是,Morphia使它非常干净和容易,比您在任何ORM中所看到的都要容易。

弃用字段

一个很好的例子是已被另一个字段替换的不推荐使用的字段。 假设您有一个错误跟踪系统,其中包含如下所示的文档:

{
  _id:1,
  desc: "IE Rendering broken on intranet site",
  componentName: "INTRANET",
  dateCreated: ISODate("2011-09-06T20:52:50.258Z")
}

这是Morphia的定义:

@Entity("issues")
class Issue {
  @Id private long id;
  private String desc;
  private String componentName;

  private Date dateCreated = new Date();
}

现在想象一下,我们决定取消组件字段,并使其成为更通用的自由文本字段,用户可以在其中输入多个组件,版本或其他有用信息。 我们不想仅仅将其放在组件字段中,因为那样会导致混乱。

值得庆幸的是,我们在Morphia工具包中有专门针对此目的的东西– @AlsoLoad批注。 此批注允许我们用多个可能的来源之一填充POJO字段。 我们只需更新Morphia映射以指示旧字段名称,就可以轻松删除对旧字段的引用而不会破坏任何内容。 这样可以使我们的代码和文档保持整洁。

@Entity("issues")
class Issue {
  @Id private long id;
  private String desc;

  @AlsoLoad("componentName") // handle old componentName field
  private String affects;

  private Date dateCreated = new Date();
}

因此,这里我们定义了旧字段的自动翻译,而无需更新文档或在POJO类中编写特殊逻辑以根据创建时间的不同来处理文档。

一个重要的提示:在这个例子中,如果这两个领域的影响和旧的组件名称字段存在,吗啡会抛出异常,所以不要尝试使用这种比自嘲领域,或者填充单场有两个相互排斥的任何其他属性。

仅支持不赞成使用的字段

另一种可能性是,您只需要在文档中支持应用程序不再写的旧字段即可。 这是一个非常简单的方法:使用@NotSaved批注。 当您在字段上使用它时,数据将被加载,但Morphia不会写入。

在前面的示例中,我们很容易决定仅支持旧字段的显示,而不将其填充到情感字段中,因此让我们对Morphia POJO进行一些更改以显示如何使用@NotSaved

@Entity("issues")
class Issue {
  @Id private long id;
  private String desc;

  private String affects;

  @NotSaved("componentName") // load old componentName field for display only
  private String componentName

  private Date dateCreated = new Date();
}

用嵌入式对象替换字段

现在,如果我们的componentName 字段实际上已更改为具有名称,版本和内部版本号的复杂组件对象? 这有点棘手,因为我们想用多个替换一个字段。 我们不能尝试从多个来源加载字段,因为它们的结构不同。 当然,我们可以使用嵌入式对象来存储复杂的组件信息,但是如何使我们的代码无缝地工作而不用更新我们的文档呢?

在这种情况下,最简单的方法是使用三个注释的组合。 首先,我们将使用@NotSaved批注标记旧字段,并引入一个新的嵌入式组件   对象使用@Embedded注释 ,最后利用Morphia提供的另一个注释– @PostLoad 。 这使我们有了一种从MongoDB填充POJO之后执行的方法。

这是示例:

@Entity("issues")
class Issue {
  @Id private long id;
  private String desc;

  private String affects;

  @NotSaved("componentName") // load old componentName to convert to component
  private String componentName

  @Embedded // our new complex Component
  private Component component;

  private Date dateCreated = new Date();
  // getters and setters ...

  @PostLoad
  protected void handleComponent() {
      if (component == null && componentName != null) {
        component = new Component(componentName, null, null);
      }
  }
}

class Component {
  private String componentName;
  private Long version;
  private Long buildNumber;

  public Component(String componentName, Long version, Long buildNumber) {
    // ...
  }

  // getters and setters ...
}

在这种情况下,我们可以删除componentName字段的getter和setter,以便我们的映射对象仅公开新的和改进的接口。

结论

通过使用Morphia通过其注释支持为我们提供的强大工具,我们可以实现以下目标:

  1. 让我们的文档结构适应应用程序并保持整洁。
  2. 在我们的Java代码中无缝处理不断变化的结构,而无需容易出错的代码。
  3. 在支持旧模式的同时仅公开新模式(确实淘汰了旧代码和字段)。

希望这可以帮助你们中的一些人适应不断发展的文档,或者至少对这些Morphia注释为您提供的功能更加熟悉。

参考: Morphia和MongoDB: Carfey软件博客上来自我们JCG合作伙伴 Craig Flichel的不断发展的文档结构


翻译自: https://www.javacodegeeks.com/2012/01/morphia-and-mongodb-evolving-document.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值