将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.mzph.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…