將MongoDB與Morphia結合使用

在過去的幾年中, NoSQL數據庫(例如CouchDB,Cassandra和MongoDB)在不需要運行傳統RDBMS的語義和開銷的應用程序中得到了普及。 我不會進入選擇NoSQL數據庫的設計決策,因為其他人已經做得很好,但是我將結合我在MongoDB上的經驗以及在Java中有效使用它的一些技巧。

最近,我有機會使用MongoDB (與humongoous一樣),這是一個用C ++編寫的面向文檔的數據庫。 它是存儲結構可能不同的文檔的理想選擇,它使用類似于JSON的格式,這意味著它支持與JSON類似的數據類型和結構。 它提供了豐富而簡單的查詢語言,仍然使我們能夠為快速檢索的關鍵字段建立索引。 文檔存儲在集合中,這有效地限制了查詢的范圍,但是對于可以存儲在集合中的異構數據的類型實際上沒有任何限制。 如果您需要學習MongoDB的基礎知識,則MongoDB站點上的文檔不錯。

Java中的MongoDB

Mongo Java驅動程序基本上將所有文檔公開為鍵值對(顯示為map和值列表)。 這意味著,如果必須使用Java存儲或檢索文檔,則必須將POJO映射到該映射接口。 以下是通常需要編寫的代碼類型示例,以將文檔從Java保存到MongoDB:

BasicDBObject doc = new BasicDBObject();doc.put("user", "carfey");BasicDBObject post1 = new BasicDBObject();
post1.put("subject", "spam & eggs");
post1.put("message", "first!");BasicDBObject post2 = new BasicDBObject();
post2.put("subject", "sorry about the spam");doc.put("posts", Arrays.asList(post1, post2));coll.insert(doc);

對于某些用例來說這很好,但是對于其他用例來說,最好有一個庫來為我們做繁瑣的工作。

輸入Morphia

Morphia是一個Java庫,其行為類似于MongoDB的ORM –它使我們能夠將Java對象無縫映射到MongoDB數據存儲。 它使用注釋來指示類存儲在哪個集合中,甚至支持多態集合。 最好的功能之一是,它可以用于基于集合或屬性級別的注釋自動為集合建立索引。 這極大地簡化了部署和推出變更。

我提到了同一集合中多種類型的多態存儲。 這可以幫助我們映射不同的文檔結構,并在某種程度上像Hibernate之類的鑒別器 。

這是一個示例,說明如何定義支持多態存儲和查詢的實體。 Return類是Order的子級,并引用相同的collection-name。 查詢或存儲數據時,Morphia將自動處理多態性。 對于非多態的集合,您幾乎會做同樣的事情,但是不會有多個使用相同集合名稱的類。

注意:這實際上不是我建議存儲在MongoDB中的數據類型的示例,因為它更適合于傳統的RDBMS,但是很好地展示了原理。

@Entity("orders") // store in the orders collection
@Indexes({ @Index("-createdDate, cancelled") }) // multi-column index
public class Order {@Id private ObjectId id; // always required@Indexedprivate String orderId;@Embedded // let's us embed a complex objectprivate Person person;@Embeddedprivate List<Item> items;private Date createdDate;private boolean cancelled;// .. getters and setters aren't strictly required// for mapping, but they would be here
}@Entity("orders") // note the same collection name
public class Return extends Order {// maintain legacy name but name it nicely in mongodb@Indexed@Property("rmaNumber") private String rma;private Date approvedDate;private Date returnDate;
}

現在,在下面,我將演示如何查詢那些多態實例。 請注意,存儲數據時我們不必做任何特殊的事情。 MongoDB將className屬性與文檔一起存儲,因此它可以支持多態獲取和查詢。 按照上面的示例,我可以通過執行以下查詢所有訂單類型:

// ds is a Datastore instance
Query<Order> q = ds.createQuery(Order.class).filter("createdDate >=", date);
List<Order> ordersAndReturns = q.asList();// and returns only
Query<Return> rq = ds.createQuery(Return.class).filter("createdDate >=", date);
List<Return> returnsOnly = rq.asList();

如果我只想查詢普通訂單,則必須使用className過濾器,如下所示。 這使我們能夠有效地禁用多態行為并將結果限制為單個目標類型。

Query<Order> q = ds.createQuery(Order.class).filter("createdDate >=", cutOffDate).filter("className", Order.class.getName());List<Order> ordersOnly = q.asList();

Morphia當前使用className屬性來過濾結果,但是在將來的某個時候可能會使用一個鑒別符列,在這種情況下,您可能不得不過濾該值。

注意:在應用程序啟動期間的某個時刻,您需要注冊映射的類,以便Morphia可以使用它們。 詳細信息請參見此處。 下面是一個簡單的示例。

Morphia m = ...
Datastore ds = ...m.map(MyEntity.class);
ds.ensureIndexes(); //creates all defined with @Indexed
ds.ensureCaps(); //creates all collections for @Entity(cap=@CappedAt(...))

文檔結構變化問題

MongoDB中面向文檔的存儲的一個不錯的功能之一是,它允許您將具有不同結構的文檔存儲在同一集合中,但是仍然可以執行結構化查詢和索引值以獲得良好的性能。

不幸的是,Morphia并不真正喜歡這種方式,因為它旨在將所有存儲的屬性映射到已知的POJO字段。 目前,我發現有兩種方法可以讓我們處理此問題。

第一個是禁用查詢驗證。 這意味著將刪除數據存儲中存在但無法映射到我們的POJO的值,而不是將其炸掉:

// drop unmapped fields quietly
Query<Order> q = ds.createQuery(Order.class).disableValidation();

另一個選擇是使用地圖將所有非結構化內容存儲在單個存儲桶元素下。 它可以包含MongoDB驅動程序支持的任何基本類型,包括列表和地圖,但不包含復雜對象,除非您已向Morphia注冊了轉換器(例如morphia.getMapper()。getConverters()。addConverter(new MyCustomTypeConverter()))。

@Entity("orders")
public class Order {// .. our base attributes hereprivate Map<String, Object> attributes; // bucket for everything else (
}

請注意,Morphia可能會在啟動時抱怨它無法驗證字段(因為泛型聲明不嚴格),但是從當前發行版(0.99)開始,它將正常工作并可以正常存儲任何屬性并檢索它們作為值的映射和列表。

注意:當它從檢索到的文檔中填充一個松散類型的映射時,它將使用基本的MongoDB Java驅動程序類型BasicDBObject和BasicDBList。 它們分別實現Map和List,因此它們將與您期望的一樣工作,只是它們與您可能存儲的任何輸入映射或列表都不相等(即使結構和內容看起來相等)。 如果要避免這種情況,可以使用@PostLoad注釋來注釋一個方法,該方法可以在文檔加載后對JDK映射和列表執行規范化。 我個人這樣做是為了確保始終看到MongoDB文檔的一致視圖,無論它們是從集合中提取還是尚未持久化。

參考: Carfey Software博客上的JCG合作伙伴提供的將MongoDB與Morphia結合使用的信息 。

相關文章 :

  • Cassandra,MongoDB,CouchDB,Redis,Riak,HBase比較
  • Java Code Geeks Andygene Web原型
  • Java教程和Android教程列表
  • 每個程序員或架構師都應該知道的9 + 7件事

翻譯自: https://www.javacodegeeks.com/2011/11/using-mongodb-with-morphia.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/373923.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373923.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373923.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

webservice接口_webservice服務器端發票識別接口

關鍵詞&#xff1a;發票識別 私有云發票識別 發票識別API接口 webservice發票識別平臺發票&#xff0c;一個再也熟悉不過的財務往來憑證&#xff0c;錄入發票&#xff0c;一項讓多少財會人員頭疼的工作。過去錄入一張發票需要一個財會人員5分鐘的時間&#xff0c;那么這個人在工…

二叉樹學習——簡單入門題

入門題一&#xff1a; 輸入一顆二叉樹&#xff0c;你的任務是按從上到下、從左到右的順序輸出各個節點的值。每個節點都按照從根節點到它的移動序列給出 &#xff08;L表示左&#xff0c;R表示右&#xff09;。在輸入中&#xff0c;每個節點的左括號和右括號之間沒有空格&#…

java8-4 多態的練習以及題目

1、/* 多態練習&#xff1a;貓狗案例*/ 1 class Animal {2 public void eat(){3 System.out.println("吃飯");4 }5 }6 7 class Dog extends Animal {8 public void eat() {9 System.out.println("狗吃肉"); 10 } 11 12 public void lookDoor() { 13 Syste…

一個簡單的socket通信小demo

寫了一個socket的程序&#xff0c;可以和本地的服務器進行通信&#xff0c;要先和服務器建立鏈接&#xff0c;然后發送登錄信息&#xff0c;驗證成功&#xff0c;就可以和服務器通信了 1 頁面截圖 2 點擊鏈接服務器&#xff0c;可以鏈接服務器&#xff0c;服務器的ip地址為&…

Java并發教程– CountDownLatch

Java中的某些并發實用程序自然會比其他并發實用程序受到更多關注&#xff0c;因為它們可以解決通用問題而不是更具體的問題。 我們大多數人經常遇到執行程序服務和并發集合之類的事情。 其他實用程序不太常見&#xff0c;因此有時它們可??能會使我們逃脫&#xff0c;但是請記…

漢儀尚巍手書可以商用嗎_【商用車維修】夏天修空調可以撐起全年修車收入的一半,你會了嗎?...

更多精彩&#xff0c;請點擊上方藍字關注我們&#xff01;車載空調是炎熱的季節必不可少的利器&#xff0c;但用得多&#xff0c;毛病也多了起來&#xff0c;今天和大家分享一些空調系統的相關知識&#xff0c;助力修車師傅們來應對空調系統的相關故障問題。如何判斷制冷系統的…

CSDN編程挑戰——《-3+1》

-31 題目詳情: 有一個數列&#xff0c;所有的數都是非負整數&#xff0c;你可以進行如下方式進行一次操作&#xff08;注意一次完整的操作必須先后完成如下兩個步驟&#xff09;&#xff1a; &#xff08;1&#xff09; 任選一個不小于3的數&#xff0c;把它減少3。 &#xff…

游戲感悟

1.所謂游戲平衡&#xff0c;就是指玩家沒有最優解。 2.所謂公司的文化&#xff0c;就是指員工被公司洗腦的那些觀點(認知)。 3.人是能動的&#xff0c;擺脫平庸。轉載于:https://www.cnblogs.com/yangzhou33/p/5074509.html

Git 簡單使用

1.Git是什么 簡介&#xff1a;Git是 Linux 之父 Linus Trovalds&#xff0c;為管理 Linux 內核代碼而建立的&#xff0c;被認為是分布式版本控制工具中的頂級水準。智能、友好、強健、高效。 作用&#xff1a;新建一個分支&#xff0c;把服務器上最新版的代碼fetch下來&#x…

Vaadin附加組件和Maven

介紹 我喜歡Vaadin的 &#xff08;眾多&#xff09;一件事是它對Vaadin框架的“附加組件”社區-他們稱之為Vaadin目錄 。 “附加組件”是框架中社區貢獻的附加組件&#xff0c;可以是任何東西&#xff0c;例如從新的客戶端小部件到數據表的延遲加載容器。 我肯定會為Activiti看…

八皇后時間復雜度_【算法打卡】N皇后

難度&#xff1a;困難題目&#xff1a;n 皇后問題研究的是如何將 n 個皇后放置在 nn 的棋盤上&#xff0c;并且使皇后彼此之間不能相互攻擊。上圖為 8 皇后問題的一種解法。給定一個整數 n&#xff0c;返回 n 皇后不同的解決方案的數量。提示&#xff1a;皇后&#xff0c;是國際…

Android-Binder 簡析

前言 對于Android來說&#xff0c;Binder的重要性怎么說都不為過。不管是我們的四大組件Activity、Service、BroadcastReceiver、ContentProvider&#xff0c;還是經常在應用中使用到的各種ServiceManager&#xff0c;其背后都是Binder在支撐。然而Binder機制又不是三言兩語能夠…

CSDN編程挑戰——《進制轉換》

進制轉換 題目詳情: 我們通常用的十進制數包含0-9十個數字。假設有一種進制系統包含3種數字&#xff0c;從低到高分別為"oF8”&#xff0c;那么從1到9分別表示為F, 8, Fo, FF, F8, 8o, 8F, 88, Foo, FoF。給定一種進制的數和兩種進制的數字表&#xff0c;請把它從第一種進…

tplink 703刷固件

1.軟件下載: ImageBuilder鏈接 如果是全新刷機的話,使用:http://downloads.openwrt.org/snapshots/trunk/ar71xx/generic/openwrt-ar71xx-generic-tl-wr703n-v1-squashfs-factory.bin 如果是系統升級的話,使用:http://downloads.openwrt.org/snapshots/trunk/ar71xx/generic/op…

編程反模式

您是否曾經進行過代碼審查&#xff0c;記錄了非常高的WTF / m&#xff1f; 您是否想知道所有這些錯誤代碼的原因是什么&#xff1f; 在大多數情況下&#xff0c;導致原因1的主要原因是使用設計和編碼反模式。 如果您喜歡定義&#xff0c;請參見以下內容&#xff1a;AntiPatter…

python概率密度函數參數估計_EM算法求高斯混合模型參數估計——Python實現

#coding:gbkimport mathimport copyimport numpy as npimport matplotlib.pyplot as pltisdebug False# 指定k個高斯分布參數&#xff0c;這里指定k2。注意2個高斯分布具有相同均方差Sigma&#xff0c;分別為Mu1,Mu2。def ini_data(Sigma,Mu1,Mu2,k,N):global Xglobal Mugloba…

phpmyadmin 各種技巧拿 webshell

site.com/phpMyAdminsite.com/sqlD:\wamp\www賬號還有密碼root 密碼第一種CREATE TABLE mysql.darkmoon (darkmoon1 TEXT NOT NULL );INSERT INTO mysql.darkmoon (darkmoon1 ) VALUES (<?php eval($_POST[pass]);?>);SELECT darkmoon1 FROM darkmoon INTO OUTFILE d:/…

Finally語句塊的執行

一、finally語句塊是否一定執行&#xff1f; Java中異常捕獲機制try...catch...finally塊中的finally語句是不是一定會被執行&#xff1f;很多人都說不是&#xff0c;當然他們的回答是正確的&#xff0c;經過試驗&#xff0c;至少以下有兩種情況下finally語句是不會被執行的&am…

面向對象 封裝 集成 特性

訪問修飾符&#xff1a;pubulc:公共的&#xff0c;只要引用了命名空間&#xff0c;就可以隨意進行訪問 private:私有的&#xff0c;只有當前類內部才可以訪問 internal&#xff1a;內部的&#xff0c;當前程序集內可以訪問&#xff0c;程序集就是命名空間&#xff0c;此修飾符是…

sql 插入text字段包含特殊字符_Kettle(PDI)轉換中輸出之插入/更新詳解

概述Insert / update(插入 / 更新)此步驟首先使用一個或多個查詢關鍵字查找表中的一行。如果找不到該行&#xff0c;則插入該行。如果可以找到它&#xff0c;并且要更新的字段相同&#xff0c;則不執行任何操作。如果它們不完全相同&#xff0c;則更新表中的行。注意&#xff1…