- 浏览: 426909 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (184)
- IDE (4)
- dotCMS (3)
- Liferay Portal (1)
- J2EE (7)
- My SQL (16)
- IBM DB2 (3)
- Oracle (2)
- JDBC (4)
- Hibernate (3)
- JSP (0)
- Framework (4)
- Java编程 (30)
- C++编程 (0)
- Struts 1.X (2)
- Struts 2.X (6)
- Linux (11)
- Spring (7)
- JavaScript (6)
- Ajax (2)
- XML (3)
- IBM Websphere Portal (1)
- IBM Lotus Quickr (1)
- CMS (2)
- ERP (0)
- CRM (0)
- 大型网站架构开发 (1)
- 面试武器 (2)
- HTML 5 (2)
- dTree && webFxloadTree (2)
- JVM (7)
- SQL Server (3)
- Tomcat && Apache && Jboss && Weblogic-中间件 (4)
- FreeMarker (2)
- MongoDB (7)
- OpenSource开源 (24)
- Cloud (0)
- FFmpeg (3)
- Thrift (1)
- SpringSide (1)
- Design Pattern (1)
- solr&&ES (2)
- git&svn (1)
- 大数据 (8)
- 人工智能 (0)
- Hadoop (3)
- Spark (0)
- Sqoop (1)
- Flume (1)
- Hive (3)
- HDFS (4)
- ES (0)
- Redis (1)
- Kafka (3)
- MR (0)
- 机器学习 (0)
- 深度学习 (0)
- Impala (2)
- HBase (2)
- Spring Boot (1)
- Spring Cloud (0)
- 大数据架构 (6)
- 架构思想理论 (6)
- 技术管理 (4)
- 数据结构与算法 (4)
最新评论
-
huijz:
...
Spring Data JPA研究-使用Spring Data JPA 简化JPA 开发(ZZ) -
用户名不存在:
[img][/img][*]引用[u][/u][i][/i][ ...
MongoDB 模糊查询的三种实现方式-morphia实现 -
junsheng100:
请给个完整的例子吧!包括jar文件等
java调用ffmpeg获取视频文件信息参数代码 -
mj:
谢谢!!
SQL Server里面如何导出包含(insert into)数据的SQL脚本 (转载ZZ)
使用 Morphia 持久保存、加载、删除和查询映射到 MongoDB 的 Java 域模型
简介: MongoDB 是面向文档的开源数据库,Morphia 是面向 MongoDB 的类型安全的对象映射库。本文解释了在文档和对象之间进行映射的好处,并演示了如何使用 Morphia 来实现这个功能。然后演示了如何持久保存、加载、删除和查询映射到 MongoDB 的 Java™ 域模型。
文章中对于 MongoDB 术语的翻译为:
- Collection:集合
- Document:文档
MongoDB 是面向文档的数据库,用于存储并检索类似 JavaScript 对象符号(JavaScript Object Notation,JSON)的文档。由于索引、复制和分片功能的增强,MongoDB 已成为强大的、可扩展的 NoSQL 竞争者(参见 参考资料)。
官方 Java 驱动程序可用于与 MongoDB 交互。该驱动程序提供 Map
的实现 BasicDBObject
,用于在数据存储中表示文档。虽然 Map
表示法很方便,尤其是在读对 JSON 序列化和反序列化时,但是能够将文档表示为 Java 类层次也具有其优点。例如,反复从 Java 域模型映射文档,允许您在 Java 层上强行执行类型安全,同时通过 MongoDB 享受无模式(schema)开发的好处。
Morphia 是基于 Apache 许可证的 Google Code 项目,让您在 MongoDB 上持久保存、检索、删除和查询作为文档存储的 POJO。通过提供一系列围绕 Mongo Java 驱动程序的注释和包装程序,Morphia 完成了这些操作。Morphia 概念上类似于对象关系映射器(ORM),如 Java Persistence API (JPA) 或 Java 数据对象(Java Data Objects,JDO)实现。在本文中,我将演示如何对映射到 MongoDB 的 Java 域模型使用 Morphia。参见 下载 部分获取完整的样例代码。
我将使用简化的域模型来演示 Morphia 的功能。BandManager(假想的 web 应用程序)提供有关音乐活动的数据:其成员、经销商、目录、类型等等。我将定义 Band
、Song
、Distributor
和 ContactInfo
类来表示此域模型,如图 1 所示:
图 1. BandManager 的类
图 1 中的统一建模语言(Unified Modeling Language,UML)显示了域模型类层次。左侧的矩形表示 Band
类。右侧的矩形分别表示ContactInfo
、Distributor
和 Song
类。从 Band
指向 ContactInfo
的箭头在 ContactInfo
旁边标有一个 1,这说明两个类之间是一对一的关系。连接 Band
到 Distributor
的线在 Band
旁边标有 0..* 且在 Distributor
旁边标有一个 1,这说明 Band
具有单一的Distributor
且 Distributor
表示许多 Band
。最后,从 Band
到 Song
的箭头在 Song
旁边标有目录 0..1,这说明 Band
具有与 Song
的一对多关系且这种关系被称作 catalog
。
我将对这些类进行注释,然后使用 Morphia 的 Datastore
接口在 MongoDB 上将它们保存为文档。
清单 1 显示了如何注释 Band
类:
清单 1. Band.java
@Entity("bands")
public class Band {
@Id
ObjectId id;
String name;
String genre;
@Reference
Distributor distributor;
@Reference("catalog")
List<Song> songs = new ArrayList<Song>();
@Embedded
List<String> members = new ArrayList<String>();
@Embedded("info")
ContactInfo info;
|
@Entity
注释是必需的。其声明了在专用集合(collection)上该类作为文档将持久保存。提供给 @Entity
注释的值(bands
)定义了如何命名集合。在默认情况下,Morphia 使用类名称来命名集合。例如,如果我遗漏了 bands
值,则在数据库中该集合将被称为Band
。
数据类型
MongoDB 比 Java 语言支持更小的数据类型集合,即integer
、long
、double
和 string
。Morphia 可自动为您转换基本 Java 类型(如 float
)。
@Id
注释指示 Morphia 哪个字段用作文档 ID。如果您试图持久保存对象(其 @Id
注释的字段为 null),则 Morphia 会为您自动生成 ID 值。
Morphia 试图持久保存每一个它遇到的没有注释的字段,除非它们标有@Transient
注释。例如,在文档中 name
和 genre
属性将被保存为string
,并具有 name
和 genre
键。
distributor
、songs
、members
和 info
属性引用其他对象。除非注释有@Reference
(不久将看到),否则成员对象将被视为嵌入的(embedded)。它会显示为集合中父文档的子集。例如,在持久保存时,members List
看上去如下所示:
"members" : [ "Jim", "Joe", "Frank", "Tom"]
|
info
属性是另外一个嵌入的对象。在本例中,我通过 info
值明确地设置 @Embedded
注释。这会覆盖文档中子集的默认命名,否则就会被称为 contactInfo
。例如:
"info" : { "city" : "Brooklyn", "phoneNumber" : "718-555-5555" }
|
@Reference 和 DBRefs
在后台,Morphia 使用 Mongo DBRef
来在不同集合中引用对象。
使用 @Reference
注释说明对象是对另外一个集合中的文档的引用。在从 Mongo 集合中加载对象时,Morphia 遵循着这些引用来建立对象图。例如,在持久保存的文档中,distributor
属性看起来如下所示:
"distributor" : { "$ref" : "distributors", "$id" : ObjectId("4cf7ba6fd8d6daa68a510e8b") }
|
正如 @Embedded
注释一样,@Reference
可以采用一个值来覆盖默认命名。在本例中,我将 songs
的 List
称为文档中的 catalog
。
现在看一下 Song
、Distributor
和 ContactInfo
的类定义。清单 2 显示了 Song
的定义:
清单 2. Song.java
@Entity("songs")
public class Song {
@Id
ObjectId id;
String name;
|
清单 3 显示了 Distributor
的定义:
清单 3. Distributor.java
@Entity("distributors")
public class Distributor {
@Id
ObjectId id;
String name;
@Reference
List<Band> bands = new ArrayList<Band>();
|
清单 4 显示了 ContactInfo
的定义:
清单 4. ContactInfo.java
public class ContactInfo {
public ContactInfo() {
}
String city;
String phoneNumber;
|
ContactInfo
类缺少 @Entity
注释。这是故意而为的,因为我不需要 ContactInfo
的专用集合。实例总是被嵌入 band
文档。
现在我已经定义并注释了域模型,我将向您展示如何使用 Morphia 的 Datastore
以便保存、加载和删除实体。
依赖注入(Dependency injection,DI)
Datastore
和 Mongo 都是 DI 友好型。例如,在 Spring 或 Guice 中,您不应该在连接它们的问题上遇到任何麻烦。如果有可能,您应该配置每一个作为单一实例并在合作(collaborating)bean 之间共享它们。
Datastore
接口 — Mongo Java 驱动程序的包装程序 — 用于在 MongoDB 中管理实体。因为 Datastore
需要 Mongo 实例以进行实例化,您可以重新使用现有的 Mongo 实例或为您的环境适当地配置一个实例。下面是一个实例化 Datastore
的示例,其连接到本地 MongoDB 实例:
Mongo mongo = new Mongo("localhost");
Datastore datastore = new Morphia().createDatastore(mongo, "bandmanager");
|
下一步我将创建 Band
实例:
Band band = new Band();
band.setName("Love Burger");
band.getMembers().add("Jim");
band.getMembers().add("Joe");
band.getMembers().add("Frank");
band.getMembers().add("Tom");
band.setGenre("Rock");
|
现在我拥有了 Band
实例,我可以使用 datastore
来持久保存它:
datastore.save(band);
|
band
现在应该保存在 bandmanager
数据库中被称为 bands
的集合中。通过使用 Mongo 命令行界面客户端,我可以查看一下以便确保(在本示例和其他示例中,折行以便适合本文页面的宽度):
> db.bands.find();
{ "_id" : ObjectId("4cf7cbf9e4b3ae2526d72587"), "className" :
"com.bandmanager.model.Band", "name" : "Love Burger", "genre" : "Rock",
"members" : [ "Jim", "Joe", "Frank", "Tom" ] }
|
这真是太棒了!它就在这里。除了 className
字段以外,一切看起来正如您所期望的。Morphia 自动创建此字段以便记录 MongoDB 中的对象类型。其主要用于确定在编译时不必知道的对象类型(例如,在您从具有混合类型的集合中加载对象时)。如果这个困扰了您且您知道您不需要该功能,那么通过将 noClassnameStored
值添加到 @Entity
注释,您可以禁用持久保存 className
:
@Entity(value="bands",noClassnameStored=true)
|
现在我将加载 Band
并断言它等同于我所持久保存的 band
:
assert(band.equals(datastore.get(Band.class, band.getId())));
|
Datastore
的 get()
方法允许您使用实体的 ID 加载该实体。您无需指定集合或定义查询字符串来加载对象。您只需告诉 Datastore
,您想加载哪个类及其 ID。Morphia 进行其余的操作。
现在可以查看 Band
的合作对象了。我开始先定义一些 Song
,然后将它们添加到我刚刚创建的 Band
实例:
Song song1 = new Song("Stairway");
Song song2 = new Song("Free Bird");
datastore.save(song1);
datastore.save(song2);
|
如果我在 Mongo 中查看 songs
集合,我应该看到如下所示:
> db.songs.find();
{ "_id" : ObjectId("4cf7d249c25eae25028ae5be"), "className" :
"com.bandmanager.model.Song", "name" : "Stairway" }
{ "_id" : ObjectId("4cf7d249c25eae25038ae5be"), "className" :
"com. bandmanager.model.Song", "name" : "Free Bird" }
|
请注意 Song
还没有从 band
引用。我将它们添加到 band
并查看发生了什么:
band.getSongs().add(song1);
band.getSongs().add(song2);
datastore.save(band);
|
现在我查询 bands
集合时,我应该看到:
{ "_id" : ObjectId("4cf7d249c25eae25018ae5be"), "name" : "Love Burger", "genre" : "Rock",
"catalog" : [
{
"$ref" : "songs",
"$id" : ObjectId("4cf7d249c25eae25028ae5be")
},
{
"$ref" : "songs",
"$id" : ObjectId("4cf7d249c25eae25038ae5be")
}
], "members" : [ "Jim", "Joe", "Frank", "Tom"] }
|
事务
非常重要的是记住 MongoDB 不像大多数关系数据库管理系统那样支持事务。如果您的应用程序需要协调多个线程写入或读取集合,您就必须依靠 Java 语言的序列化和并发功能。
请注意 songs
集合如何被保存为一个被称为 catalog
的数组,作为两个DBRef
。
现在的限制是引用的对象必须先被保存,然后其他对象才能引用它们。这解释了为什么我先保存 song1
和 song2
,然后将它们添加到 band
。
现在我将删除 song2
:
datastore.delete(song2);
|
查询 songs
集合应该说明没有了 song2
。但是如果您查看 band
,您将看到该歌曲仍在那里。更糟糕的是,试图加载 band
实体会导致异常:
Caused by: com.google.code.morphia.mapping.MappingException: The
reference({ "$ref" : "songs", "$id" : "4cf7d249c25eae25038ae5be" }) could not be
fetched for com.bandmanager.model.Band.songs
|
现在,要避免此错误,您需要在删除歌曲以前手动删除对它的引用。
到目前为止,通过其 ID 加载实体只能得到实体的信息。最终我希望能够查询 Mongo 并得到我想要的实体。
我将通过名称查询 band
,而不是通过其 ID 加载它。为此,我通过创建 Query
对象并指定筛选器来获得我希望的结果:
Query query = datastore.createQuery(Band.class).filter("name = ","Love Burger");
|
我指定了想要查询的类,即 Band
,和针对 createQuery()
方法的筛选器。一旦我定义了查询,我就可以使用 asList()
方法来访问结果:
Band band = (Band) query.asList().get(0);
|
Morphia 的筛选运算符紧密地映射到用于 MongoDB 查询的查询运算符。例如,我在上面查询中使用的 =
运算符就类似于 MongoDB 中的 $eq
运算符。有关筛选运算符的全部细节都在 Morphia 在线文档中(参见 参考资料)。
作为筛选查询的替代,Morphia 为构建查询提供了更好的接口。例如,以下接口查询等同于以前的筛选查询:
Query query = datastore.createQuery(Band.class).field("name").equal("Love Burger");
|
您可以使用“点注释”来查询嵌入的对象。下面是使用点注释和接口的查询,用于选择位于 Brooklyn 的所有乐队:
Query query = datastore.createQuery(Band.class).field("info.city").equal("Brooklyn");
|
您可以进一步定义查询结果集。我将修改以前的查询以便根据名称来对乐队排序并将结果限制为 100:
Query query =
datastore.createQuery(Band.class).field("info.city").equal
("Brooklyn").order("name").limit(100);
|
您将注意到随着您的集合增长查询性能将会降低。Mongo 集合(非常像关系数据库表)需要正确进行索引以便确保合理的查询性能。
通过 @Indexed
注释对属性进行注释会对该字段应用索引。这里,我对 Band
的 genre
属性创建了一个名为 genreName
的升序索引:
@Indexed(value = IndexDirection.ASC, name = "genreName")
String genre;
|
要应用索引,Morphia 需要知道映射哪些类。您需要以稍微不同的方式实例化 Morphia 以便确保应用索引。您可以按如下所示执行:
Morphia morphia = new Morphia();
morphia.mapPackage("com.bandmanager.model");
datastore = morphia.createDatastore(mongo, "bandmanager");
datastore.ensureIndexes();
|
最终的 ensureIndexes()
调用可以指示数据存储创建所需且不存在的索引。
索引还可用于避免将重复项插入到集合中。例如,通过在 band
名称的 @Indexed
注释上设置 unique
属性,我可以确保在该集合中只有一个具有给定名称的 band
:
@Indexed(value = IndexDirection.ASC, name = "bandName", unique = true)
String name;
|
随后同名的 band
将被丢弃。
Morphia 是与 MongoDB 进行交互的强大工具。它允许对 MongoDB 文档进行类型安全的、惯用的访问。本文涵盖了使用 Morphia 的主要方面,但排除了一些功能。要获得有关其数据访问对象(Data Access Object,DAO)支持、验证和手动映射功能的信息,我鼓励您查看 Morphia Google Code 项目。
From :http://www.ibm.com/developerworks/cn/java/j-morphia/index.html?ca=drs-
===================================================================================
Morphia 地址:http://code.google.com/p/morphia/ 教程:http://code.google.com/p/morphia/wiki/QuickStart MongoDB 自己带的java API只能是保存 DBObject 对象的子类,类似BasicDBObject,如果对象有很多的字段,那是很繁琐的,需要一个个的put,地球人不爱干这样的事情,于是Morphia就出现了。 创建Meeting对象
用法示例:MeetingDaoTes.java ---------------------------------- package com.spell; |
- j-morphia.zip (17.3 KB)
- 下载次数: 2
发表评论
-
MongoDB数据库导出、导入与备份、恢复
2012-07-24 16:49 6117MongoDB导入命令: mon ... -
MonjaDB -基于Eclipse的 MongoDB 的 GUI 客户端工具
2012-07-09 19:51 2103MonjaDB 是一个 MongoDB 的 GUI 客户端工具 ... -
MongoDB 模糊查询的三种实现方式-morphia实现
2012-06-15 17:53 20882MongoDB 模糊查询的三种实现方式-morphia实现如下 ... -
MongoDB 增加用户 删除用户 修改用户 读写权限 只读权限
2012-03-27 10:52 1657MongoDB 增加用户 删除用户 修改用户 读写 ... -
MongoDB管理工具RockMongo(ZZ)
2012-03-21 18:10 1988rock_mongo_zh PHP5写的一个Mon ... -
MongoDB的使用-主流NOSQL数据库之MongoDB快速入门
2011-08-26 18:05 1754目前,NOSQL在业界正发展的如火如荼,其中Mongodb是其 ...
相关推荐
本文解释了在文档和对象之间进行映射的好处,并演示了如何使用Morphia来实现这个功能。然后演示了如何持久保存、加载、删除和查询映射到 MongoDB的Java域模型。MongoDB是面向文档的数据库,用于存储并检索类似...
MongoDB是一种流行的开源、分布式文档数据库,常用于处理大规模数据。在Java开发中,Morphia是一个优秀的对象数据映射(ODM...通过学习和实践,你将能够充分利用Morphia框架的强大功能,实现高效、灵活的MongoDB操作。
2. **分布式架构**:MongoDB支持分布式部署,可以通过复制集和分片实现高可用性和水平扩展。 3. **灵活查询**:MongoDB的查询语言非常强大,可以进行复杂的聚合操作,并支持丰富的查询表达式。 4. **网格FS**:...
morphia基于mongodb的基本开发
MongoDB是一款流行的NoSQL数据库系统,以其灵活的数据模型、高可用性和可扩展性而受到广泛欢迎。Morphia是针对MongoDB的一个Java持久层框架,它提供了简单易用的API,使得开发者能够方便地在Java应用程序中操作...
MongoDB 是一个流行的开源文档数据库系统,以其灵活性和高性能而受到开发者欢迎。Morphia 是一个 Java ORM(对象关系映射)库,用于简化 MongoDB 的数据操作,将数据模型与数据库文档之间的转换自动化。在本文中,...
【Morphia 操作 MongoDB 知识点详解】 ...通过 Morphia,你可以更便捷地进行 MongoDB 的增删查改操作,同时享受到 Java 语言的强大和灵活性。它简化了数据模型的设计,使得数据库操作更加直观和高效。
MongoDB是一种流行的NoSQL数据库系统,它以JSON格式存储数据,具有高度的可扩展性和灵活性。Morphia是为MongoDB设计的一个强大的Object Document Mapper (ODM)库,它允许Java开发者以面向对象的方式与MongoDB进行...
要求JDK 7+ Gradle您可以在localhost:27017上使用独立的MongoDB服务器,或者如果该服务器不可用,则测试代码将启动嵌入式MongoDB进程。入门在基本文件夹( build.gradle文件所在的位置)内,运行以下命令以开始使用...
中断更改:play-morphia 1.5.0将morphia库更新为org.mongodb.morphia 0.107。 请在您的应用程序中将文本从“ com.google.code.morphia”替换为“ org.mongodb.morphia” PlayMorphia概述 PlayMorphia模块一个功能...
标题中的“morphia.jar”和“mongo.jar”指的是两个与MongoDB数据库操作相关的Java库文件。MongoDB是一个流行的开源、分布式文档型数据库,而Morphia则是Java开发人员用来操作MongoDB的一个对象数据映射(ODM)框架...
Spring MVC、Morphia 和 MongoDB 是三个在Java开发中常用于构建Web...通过深入研究这个例子,你将能理解如何在实际项目中结合使用Spring MVC、Morphia和MongoDB,从而更好地掌握Java Web开发中的非关系型数据库集成。
MongoDB是一种流行的开源、分布式文档数据库,常用于构建高性能、高可用性和可扩展性的现代应用程序。在本项目“mongodbWeb”中,结合Spring MVC框架和Morphia库,实现了对MongoDB数据库的操作封装,便于在Web应用中...
例如,通过实现自定义的Repository接口,我们可以利用Morphia的查询能力,同时享受Spring Data的自动化和灵活性。 在`spring-mongodb-morphia-master`这个项目中,你可以找到实际的代码示例,了解如何配置Spring ...
在本文中,我们将探讨MongoDB的ORM框架Morphia,并结合Spring Data MongoDB的使用来创建一个集成应用。ORM(对象关系映射)框架是将数据库操作转化为对象模型的方法,简化了开发过程,使得开发者可以专注于业务逻辑...
后续提交放在https://github.com/zdsiyan/watermelon 上, 用eclipse导入该工程需安装m2eclipse,jetty等查件. 另外.settings下的org.eclipse.wst.common.component文件如下: ...</project-modules>
此外,教程可能还会涉及复制集和分片,这是MongoDB实现高可用性和可扩展性的关键特性。 其次,"java调用mongodb的pdf文档"将深入到Java开发者如何在应用程序中集成和操作MongoDB。Java驱动程序是MongoDB官方支持的...