自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MongoDB、Java與對象關(guān)系映射

開發(fā) 后端 MongoDB
當(dāng)今NoSQL領(lǐng)域中有很多有力的競爭者通過多種方式來處理海量數(shù)據(jù)問題。其中重要的解決方案之一就是MongoDB。MongoDB是面向文檔的弱結(jié)構(gòu)化存儲方案,使用JSON格式來展現(xiàn)、查詢和修改數(shù)據(jù)。

MongoDB介紹

當(dāng)今NoSQL領(lǐng)域中有很多有力的競爭者通過多種方式來處理海量數(shù)據(jù)問題。其中重要的解決方案之一就是MongoDB。MongoDB是面向文檔的弱結(jié)構(gòu)化存儲方案,使用JSON格式來展現(xiàn)、查詢和修改數(shù)據(jù)。

MongoDB文檔相當(dāng)完備,擴(kuò)展規(guī)模與安裝一樣簡單。它提供冗余、切片、索引以及map/reduce等概念支持。MongoDB的開源社區(qū)非常大且非常活躍。MongoDB在很多大型產(chǎn)品中被實(shí)際運(yùn)用,如:Disney, Craigslist, Foursquare, Github 和SourceForge。MongoDB是一個開源項(xiàng)目,由10gen.com建立并維護(hù),該公司由DoubleClick的前任執(zhí)行人員創(chuàng)立。同時(shí),10gen也提供了極好的商業(yè)支持與參與建設(shè)。

 

MongoDB 與 NoSQL: 缺陷與優(yōu)勢

MongoDB作為一個可用NoSQL方案具有很多優(yōu)勢。我剛開始接觸nosql數(shù)據(jù)庫了解了一系列基于Java的方案,并且花了大量的時(shí)間來弄懂什么是列家族,Hadoop與HBase的關(guān)系,ZooKeeper到底是什么。當(dāng)我終于全部清楚之后,發(fā)現(xiàn)Cassandra與HBase確實(shí)是對于NoSQL領(lǐng)域非常可靠、可信賴的解決方案。但與其他的解決方案相比,MongoDB讓我在能夠開始寫代碼之前,不用理解那么多的概念。

與其他軟件相似,MongoDB也存在缺陷。經(jīng)過一段時(shí)間使用MongoDB,我列舉經(jīng)歷過并需要注意的一些事情,我成為“Gotchas”:

● 不要按照關(guān)系型數(shù)據(jù)庫來思考。這很明顯,MongoDB使得構(gòu)建和執(zhí)行復(fù)雜查詢變得非常容易。當(dāng)實(shí)際使用的時(shí)候,你會主要關(guān)注于效率問題(像我一樣)。

● MongoDB的索引是二進(jìn)制的樹。如果你不是很熟悉B-tree,可能需要了解一下。這些都涉及到構(gòu)建符合提供查詢條件需求的建立索引的方式。

● 小心的設(shè)計(jì)索引結(jié)構(gòu)。這涉及到上面提到的B-tree。剛開始我的索引包含文檔中的很多字段,以防我會使用到他們。不要犯同樣的錯誤。我有一個很小集合的索引(大約1千萬記錄)增長到超過17GB的空間,比集合本身還大。你應(yīng)該不會想要索引一個包含成百上千個實(shí)體的列表字段。

● MongoDB采用了非常有意思的方式來實(shí)現(xiàn)NoSQL:采用BSON作為存儲,JSON作為展示,JavaScript用于管理和Map/Reduce。因此也引起了一些小問題比如這個 (破壞了Number和Long的相等操作),在MongoDB逐漸流行之后,可能會不斷的展示出來。

 

MongoDB, 命令行與驅(qū)動

MongoDB基本是使用JavaScript客戶端命令行程序來進(jìn)行復(fù)雜任務(wù)管理的,如數(shù)據(jù)整合和簡單信息處理,編程都是完全使用JavaScript語言來的。本文中,我們會展示命令行的使用示例。現(xiàn)在有大量的MongoDB客戶端產(chǎn)品提供,并且由MongoDB社區(qū)來支持驅(qū)動。通常每種編程語言都有驅(qū)動,并且所有流行的語言都有包括,一些不那么流行的也包含在內(nèi)。這篇文章展示了使用MongoDB的Java驅(qū)動,并使用一個ORM庫(MJORM)與之進(jìn)行比較。

 

介紹 MJORM: MongoDB的ORM方案

在解決的眾多有意思的問題中,最近NoSQL數(shù)據(jù)存儲在開發(fā)者中主要的問題趨勢就是對象關(guān)系映射。對象關(guān)系映射就是將傳統(tǒng)中保存在關(guān)系型數(shù)據(jù)庫中的持久化數(shù)據(jù)映射為在應(yīng)用程序中使用的對象。這使得編程語言使用起來更加流暢和自然。

MongoDB面向文檔的架構(gòu)使得它非常適合對象關(guān)系映射,因?yàn)槲臋n本身就是以對象形式存儲的??上]有太多的MongoDB的Java對象關(guān)系映射庫,但是還是有一些,如morphia-(A type-safe Java library for MongoDB), spring-data(SpringData項(xiàng)目的MongoDB實(shí)現(xiàn))

這些ORM庫大量使用了注解,因?yàn)橐恍┰驅(qū)ξ也贿m合,其中最重要的就是這些被注解的對象在多個項(xiàng)目中的兼容性問題。這讓我開始了mongo-Java-orm 或者 “MJORM” (發(fā)音 me-yorm)項(xiàng)目,一個MongoDB的Java對象關(guān)系映射項(xiàng)目。MJORM是在MIT許可之下,并且在發(fā)布在了google code project。項(xiàng)目采用maven構(gòu)建,并且maven構(gòu)件倉庫托管于google code版本控制服務(wù)器。MJORM的最新可用發(fā)布版本為0.15,已經(jīng)由一些項(xiàng)目使用與生產(chǎn)環(huán)境中。

 

開始使用ORM

加入MJORM 庫

Maven的使用者首先應(yīng)當(dāng)在pom.xml中加入MJORM的maven倉庫,使得MJORM構(gòu)件可用。

  1. <repository>  
  2.     <id>mjorm-webdav-maven-repo</id>  
  3.     <name>mjorm maven repository</name>  
  4.     <url>http://mongo-Java-orm.googlecode.com/svn/maven/repo/</url>  
  5.     <layout>default</layout>  
  6. </repository> 

然后加入依賴:

  1. <dependency>  
  2.     <groupId>com.googlecode</groupId>  
  3.     <artifactId>mongo-Java-orm</artifactId>  
  4.     <version>0.15</version>  
  5. </dependency> 

這樣就可以在應(yīng)用中引入MJORM代碼。假如沒有使用maven,則你需要手動下載MJORM的pom.xml中列舉的所有依賴。 建立 POJOs依賴已經(jīng)導(dǎo)入,可以開始編碼了。我們從POJO開始:

  1. class Author {  
  2.     private String firstName;  
  3.     private String lastName;  
  4.     // ... setters and getters ...  
  5. }  
  6.    
  7. class Book {  
  8.     private String id;  
  9.     private String isbn;  
  10.     private String title;  
  11.     private String description;  
  12.     private Author author;  
  13.     // ... setters and getters ...  

我們在這個對象模型中的描述是,作者有ID、姓和名,書有ID、ISNB、標(biāo)題、描述和作者。 你可能注意到書的id屬性是一個字符串,這是為了適應(yīng)MongoDB的對象ID類型。MongoDB的ID是一個12字節(jié)的二進(jìn)制值顯示為一個十六進(jìn)制的字符串。MongoDB要求集合中的每個文檔都必須有一個唯一id,但不要求一定要是ObjectId。目前MJORM只支持ObjectId,并且顯示為字符串。 你也可能注意到了Author沒有id字段。這是因?yàn)锽ook是它的父文檔,因此不需要有id。記住,MongoDB只要求集合中的文檔在根級別的id。 創(chuàng)建XML映射文件 下一個步驟就是建立XML映射文件,MJORM能夠?qū)ongoDB文檔轉(zhuǎn)換為對象。我們?yōu)槊總€文檔創(chuàng)建一個對象作為示范,無論將所有的映射放在一個XML文件中還是分開都是可以的。

Author.mjorm.xml:

  1. <?xml version="1.0"?> 
  2. <descriptors> 
  3.          <object> 
  4.                  <property name="firstName" /> 
  5.                  <property name="lastName" /> 
  6.          </object> 
  7. </descriptors> 

Book.mjorm.xml:

  1. <?xml version="1.0"?> 
  2. <descriptors> 
  3.          <object> 
  4.                  <property name="id" id="true" auto="true" /> 
  5.                  <property name="isbn" /> 
  6.                  <property name="title" /> 
  7.                  <property name="description" /> 
  8.                  <property name="author" /> 
  9.          </object> 
  10. </descriptors> 

這些映射文件能夠很好的自解釋。descriptors 元素是根元素,必須包含在每個映射文件中。在它下面是object元素定義了文檔與之對應(yīng)的類。Object包含的property 元素主要用于描述POJO中的屬性以及這些屬性如何與MongoDB中的文檔想對應(yīng)。property 元素至少必須包含一個name 屬性,這個元素就是POJO和MongoDB的文檔中的屬性名稱。column 屬性則是可選的,用于特定一個在MongoDB文檔中的可選屬性名稱。 property 元素當(dāng)中的id屬性應(yīng)該是對象的唯一識別。一個對象只能有一個property 元素包含id屬性。auto 的設(shè)置會使得MJORM在持久化時(shí)為該屬性自動生成一個值。 可以在google code的MJORM項(xiàng)目主頁中查看XML映射文件的更多細(xì)節(jié)描述。 整合POJO與XML我們創(chuàng)建了數(shù)據(jù)模型以及映射文件,使得MJORM可以從MongoDB序列號以及反序列號POJO。我們可以進(jìn)行一些有意思的事情了,首先打開MongoDB的鏈接:

  1. Mongo mongo = new Mongo(  
  2.          new MongoURI("mongodb://localhost/mjormIsFun")); // 10gen driver 

Mongo 對象是由10gen編寫的Java驅(qū)動提供的。示例中連接了一個本地的MongoDB實(shí)例中的mjormIsFun數(shù)據(jù)庫。接下來我們創(chuàng)建MJORM ObjectMapper 。目前ObjectMapper 在MJORM中的唯一實(shí)現(xiàn)就是XmlDescriptorObjectMapper,使用XML結(jié)構(gòu)描述信息。可能之后會增加對注解或其他結(jié)構(gòu)定義的支持。

  1. XmlDescriptorObjectMapper objectMapper = new XmlDescriptorObjectMapper();  
  2. mapper.addXmlObjectDescriptor(new File("Book.mjorm.xml"));  
  3. mapper.addXmlObjectDescriptor(new File("Author.mjorm.xml")); 

建立好了XmlDescriptorObjectMapper 并且加入了映射文件。接下來建立由MJORM提供的MongoDao 對象的實(shí)例。

  1. DB db = mongo.getDB("mjormIsFun"); // 10gen driver  
  2. MongoDao dao = new MongoDaoImpl(db, objectMapper); 

首先我們要獲得10gen驅(qū)動提供的DB對象實(shí)例。然后使用DB和ObjectMapper 建立MongoDao 。我們準(zhǔn)備開始持久化數(shù)據(jù),建立一個Book 然后保存到MongoDB中。

  1. Book book = new Book();  
  2. book.setIsbn("1594743061");  
  3. book.setTitle("MongoDB is fun");  
  4. book.setDescription("...");  
  5. book = dao.createObject("books", book);  
  6. System.out.println(book.getId()); // 4f96309f762dd76ece5a9595 

首先建立Book 對象并且填值,然后調(diào)用MongoDao 的 createObject 方法,將Book 對象傳入”books” 的集合中。MJORM會按照之前的xml映射文件將Book 轉(zhuǎn)換為DBObject (這是10gen的Java驅(qū)動使用的基本類型),并保存一個新的文檔進(jìn)”books” 集合。MJORM返回Book對象時(shí),id屬性會被填充。請注意,MongoDB默認(rèn)是不需要在使用前建立數(shù)據(jù)庫或集合的,系統(tǒng)會在需要時(shí)自動創(chuàng)建,這可能會造成某些困擾。在MongoDB的命令行中查看Book對象大概如下:

  1. > db.books.find({_id:ObjectId("4f96309f762dd76ece5a9595")}).pretty()  
  2. {  
  3.          "_id":          ObjectId("4f96309f762dd76ece5a9595"),  
  4.          "isbn":         "1594743061",  
  5.          "title":        "MongoDB is fun",  
  6.          "description":  "..." 

我們來看看假如不用MJORM而直接使用10gen的Java驅(qū)動,如何使用createObject 方法:

  1. Book book = new Book();  
  2. book.setIsbn("1594743061");  
  3. book.setTitle("MongoDB is fun");  
  4. book.setDescription("...");  
  5. DBObject bookObj = BasicDBObjectBuilder.start()  
  6.          .add("isbn",              book.getIsbn())  
  7.          .add("title",             book.getTitle())  
  8.          .add("description",       book.getDescription())  
  9.          .get();  
  10. // 'db' is our DB object from earlier  
  11. DBCollection col = db.getCollection("books");  
  12. col.insert(bookObj);  
  13. ObjectId id = ObjectId.class.cast(bookObj.get("_id"));  
  14. System.out.println(id.toStringMongod()); // 4f96309f762dd76ece5a9595 

下面進(jìn)行對象的查詢:

  1. Book book = dao.readObject("books""4f96309f762dd76ece5a9595", Book.class);  
  2. System.out.println(book.getTitle()); // "MongoDB is fun" 

readObject 方法根據(jù)給定文檔的id從指定的集合中讀取文檔,轉(zhuǎn)換為對象(再次使用映射文件)并返回。 敏銳的讀者會注意到Book還沒有指定Author,仍然保存了。這歸咎于MongoDB的結(jié)構(gòu)不敏感的特性。我們不能要求集合中的文檔包含所有屬性(id屬性是必須的),所有在MongoDB中沒有Author的Book是可以的。我們現(xiàn)在為Book添加一個Author并且更新一下:

  1. Author author = new Author();  
  2. author.setFirstName("Brian");  
  3. author.setLastName("Dilley");  
  4. book.setAuthor(author);  
  5. dao.updateObject("books""4f96309f762dd76ece5a9595", book); 

現(xiàn)在Book就包含了Author,并且在MongoDB中持久化了。現(xiàn)在在命令行查看了Book:

  1. > db.books.find({_id:ObjectId("4f96309f762dd76ece5a9595")}).pretty()  
  2. {  
  3.          "_id":          ObjectId("4f96309f762dd76ece5a9595"),  
  4.          "isbn":         "1594743061",  
  5.          "title":        "MongoDB is fun",  
  6.          "description":  "..." 
  7.          "author": {  
  8.              "firstName""Brian",  
  9.              "lastName""Dilley" 
  10.          }  

可以看到持久化的Book中已經(jīng)包含了author。不使用MJORM來操作一遍:

  1. Author author = new Author();  
  2. author.setFirstName("Brian");  
  3. author.setLastName("Dilley");  
  4. book.setAuthor(author);  
  5. DBObject bookObj = BasicDBObjectBuilder.start()  
  6.          .add("isbn",              book.getIsbn())  
  7.          .add("title",             book.getTitle())  
  8.          .add("description",       book.getDescription())  
  9.          .push("author")  
  10.                  .add("firstName",         author.getFirstName())  
  11.                  .add("lastName",  author.getLastName())  
  12.                  .pop()  
  13.          .get();  
  14. DBCollection col = db.getCollection("books");  
  15. col.update(new BasicDBObject("_id", bookObj.get("_id")), bookObj); 

對于MongoDao 方法的深入討論已經(jīng)超出了本文的范圍。對于將MJORM有興趣用于實(shí)際項(xiàng)目中的用戶強(qiáng)烈建議了解一下MJORM項(xiàng)目提供的相關(guān)文檔,或者M(jìn)ongoDao 接口提供的相關(guān)用法。

 

總結(jié)

希望這篇文章對MongoDB和MJORM的亮點(diǎn)有所展示。MongDB是一個優(yōu)秀的呃NoSQL數(shù)據(jù)存儲,有著大量優(yōu)秀的特性,會是NoSQL市場中長期競爭者。若你會在一個Java項(xiàng)目中使用MongoDB,希望你也能夠考慮使用MJORM作為你的ORM框架。十分歡迎大家提交特性需求、錯誤異常報(bào)告、文檔和源碼修正。

 

作者 Bio

Brian Dilley 是一個經(jīng)驗(yàn)豐富的高級工程師以及項(xiàng)目領(lǐng)導(dǎo),在Java/Java EE /Spring Framework/Linux內(nèi)部結(jié)構(gòu)理解和管理有著超過13年的經(jīng)驗(yàn)。Brian對于創(chuàng)業(yè)公司有很多經(jīng)驗(yàn),推向市場,構(gòu)建/維護(hù)產(chǎn)品等。他是Iaas、cloud、PHP和Linux的專家,熟悉產(chǎn)品的采購、安裝及配置定義,以及公司的軟硬件架構(gòu)包括負(fù)載均衡、數(shù)據(jù)庫、微博等。可以follow Brian的 Twitter 。

 

英文原文:Brian Dilley 本文由陳晨(@一酌散千憂)編譯并投稿于伯樂在線。如果您也愿意 分享一份自己的原創(chuàng)/譯文,可以 從這里開始~

原文鏈接:http://blog.jobbole.com/19125/

【編輯推薦】

  1. 法官裁定Google侵犯Oracle Java版權(quán)
  2. Java集合框架總結(jié):TreeSet類的排序問題
  3. K-means算法的Java實(shí)現(xiàn) 聚類分析681個三國武將
  4. 淺析Java web程序之客戶端和服務(wù)器端交互原理
  5. 詳解Java類的生命周期
責(zé)任編輯:林師授 來源: 伯樂在線
相關(guān)推薦

2009-09-23 13:26:10

Hibernate對象

2012-02-08 12:17:38

HibernateJava

2021-10-18 10:54:46

xDSEnvoy代理

2012-05-30 15:03:43

ibmdw

2021-11-11 17:36:07

鴻蒙HarmonyOS應(yīng)用

2021-02-22 06:41:35

對象AutoMapper映射

2010-09-16 14:37:54

DataSetXML

2021-09-03 15:41:00

鴻蒙HarmonyOS應(yīng)用

2009-09-25 12:59:52

Hibernate映射

2009-09-15 11:29:04

LINQ to SQL

2009-06-18 14:22:06

Hibernate多對Hibernate

2021-09-03 15:27:17

鴻蒙HarmonyOS應(yīng)用

2009-07-06 15:47:11

Servlet API

2010-06-13 10:19:24

面向?qū)ο蠹夹g(shù)與UML

2023-08-29 09:00:00

JavaScript工具

2011-04-25 17:15:39

MongodbMMAP

2009-06-02 14:46:26

Hibernate關(guān)系映射教程

2010-06-17 18:57:11

UML對象關(guān)系

2021-05-31 06:28:35

AutoMapper對象映射器

2013-03-28 09:55:37

Java對象
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號