morphia_Morphia和MongoDB:不断发展的文档结构
morphia
在我先前關(guān)于Morphia的帖子中 ,我介紹了一些典型用法,并提到了一些已知問題的警告和解決方法。 我展示了使用Morphia的工作有多么容易,以及它與Java世界的交互方式有多么干凈。為了跟進(jìn)該帖子的后續(xù)內(nèi)容,我將討論如何處理一些現(xiàn)實(shí)生活中的需求:處理更改的架構(gòu)并自定義映射以處理諸如只讀字段之類的事情,并用復(fù)雜的對(duì)象替換簡(jiǎn)單的字段。
變更架構(gòu)
幾乎所有在開發(fā)領(lǐng)域中使用過數(shù)據(jù)庫的人都知道,模式一直在發(fā)展。 不推薦使用或完全刪除字段,過時(shí)的表,添加新的字段等等。
盡管通過使用像MongoDB這樣的無模式數(shù)據(jù)存儲(chǔ)可以避免很多麻煩,但有時(shí)我們?nèi)匀恍枰獙?duì)更改進(jìn)行特殊處理,而對(duì)于Morphia,我們本質(zhì)上已經(jīng)定義了模式,因此我們必須找到處理方法。這個(gè)。 最好的一點(diǎn)是,Morphia使它非常干凈和容易,比您在任何ORM中所看到的都要容易。
棄用字段
一個(gè)很好的例子是已棄用的字段,而該字段已被另一個(gè)字段替換。 假設(shè)您有一個(gè)錯(cuò)誤跟蹤系統(tǒng),其中包含如下所示的文檔:
{_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(); }現(xiàn)在想象一下,我們決定取消component字段,并使它成為更通用的自由文本字段,用戶可以在其中輸入多個(gè)組件,版本或其他有用的信息。 我們不想只是將其放在組件字段中,因?yàn)檫@會(huì)導(dǎo)致混亂。
值得慶幸的是,我們?cè)贛orphia工具包中有一個(gè)專門為此而制作的東西– @AlsoLoad批注。 此批注允許我們用多個(gè)可能的來源之一填充POJO字段。 我們只需更新Morphia映射以指示舊字段名稱,就可以輕松刪除對(duì)舊字段的引用而不會(huì)破壞任何內(nèi)容。 這樣可以使我們的代碼和文檔保持整潔。
@Entity("issues") class Issue {@Id private long id;private String desc;@AlsoLoad("componentName") // handle old componentName fieldprivate String affects;private Date dateCreated = new Date(); }因此,這里我們定義了舊字段的自動(dòng)翻譯,而無需更新文檔或在POJO類中編寫特殊邏輯以根據(jù)創(chuàng)建時(shí)間的不同來處理文檔。
一個(gè)重要的提示:在這個(gè)例子中,如果這兩個(gè)領(lǐng)域的影響和舊的組件名稱字段存在,嗎啡會(huì)拋出異常,所以不要嘗試使用這種比自嘲領(lǐng)域,或者填充單場(chǎng)有兩個(gè)相互排斥的任何其他屬性。
僅支持不贊成使用的字段
另一種可能性是,您只需要在文檔中支持應(yīng)用程序不再寫的舊字段即可。 這是一個(gè)非常簡(jiǎn)單的方法:使用@NotSaved批注。 當(dāng)您在字段上使用它時(shí),數(shù)據(jù)將被加載但Morphia不會(huì)寫入。
在前面的示例中,我們很容易決定僅支持舊字段的顯示,而不將其填充到情感字段中,因此讓我們對(duì)Morphia POJO進(jìn)行一些更改以顯示如何使用@NotSaved 。
@Entity("issues") class Issue {@Id private long id;private String desc;private String affects;@NotSaved("componentName") // load old componentName field for display onlyprivate String componentNameprivate Date dateCreated = new Date(); }用嵌入式對(duì)象替換字段
現(xiàn)在,如果我們的componentName 字段實(shí)際上已更改為具有名稱,版本和內(nèi)部版本號(hào)的復(fù)雜組件對(duì)象? 這有點(diǎn)棘手,因?yàn)槲覀兿胗枚鄠€(gè)替換一個(gè)字段。 我們不能嘗試從多個(gè)來源加載字段,因?yàn)樗鼈兙哂胁煌慕Y(jié)構(gòu)。 當(dāng)然,我們可以使用嵌入式對(duì)象來存儲(chǔ)復(fù)雜的組件信息,但是如何使代碼無縫地工作而又不必更新文檔?
在這種情況下,最簡(jiǎn)單的方法是使用三個(gè)注釋的組合。 首先,我們將使用@NotSaved批注標(biāo)記舊字段,并引入一個(gè)新的嵌入式組件 ? 對(duì)象使用@Embedded注釋 ,最后利用Morphia提供的另一個(gè)注釋– @PostLoad 。 這使我們有了一種從MongoDB填充POJO之后執(zhí)行的方法。
例子如下:
@Entity("issues") class Issue {@Id private long id;private String desc;private String affects;@NotSaved("componentName") // load old componentName to convert to componentprivate String componentName@Embedded // our new complex Componentprivate Component component;private Date dateCreated = new Date();// getters and setters ...@PostLoadprotected 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,以便我們的映射對(duì)象僅公開新的和改進(jìn)的接口。
結(jié)論
通過使用Morphia通過其注釋支持為我們提供的強(qiáng)大工具,我們可以實(shí)現(xiàn)以下目標(biāo):
希望這可以幫助您中的一些人適應(yīng)不斷發(fā)展的文檔,或者至少可以更熟悉這些Morphia注釋為您提供的功能。
參考: Morphia和MongoDB:來自我們的JCG合作伙伴 Crafe Flichel(來自Carfey軟件博客)的 不斷發(fā)展的文檔結(jié)構(gòu)
翻譯自: https://www.javacodegeeks.com/2012/01/morphia-and-mongodb-evolving-document.html
morphia
總結(jié)
以上是生活随笔為你收集整理的morphia_Morphia和MongoDB:不断发展的文档结构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Apache JMeter教程
- 下一篇: 安卓单核多核哪个重要(安卓单核)