Java EE + MongoDb与Apache TomEE和Jongo Starter项目

知道MongoDBJava EE ,但是您不知道如何将两者集成在一起? 您是否阅读了很多有关该主题的内容,但没有找到适合该目的的解决方案? 这个入门项目适合您:

您将学习如何以一种时尚的方式使用MongoDBJava EE ,而不必依赖于Spring Data MongoDB框架,但具有“相似的”基本功能。

比Maven原型更好的唯一事情是可以使用已设置的所有内容进行存储的存储库。 跳过文档,然后进行分叉编码。 该入门项目包含:

  • Jongo如MongoDB的映射( www.jongo.org )。
  • Apache TomEE作为应用程序服务和集成。 ( tomee.apache.org )
  • 测试的Arquillian 。 ( www.arquillian.org )

该示例非常简单,我们希望将颜色存储在MongoDB集合中。

我们的POJO就像:

public class Color {@ObjectIdprivate String _id;private String name;private int r;private int g;private int b;public Color() {super();}public Color(String name, int r, int g, int b) {super();this.name = name;this.r = r;this.g = g;this.b = b;}// getters and setters
}

请注意,我们正在使用Jongo提供的@ObjectId批注将此字段设置为MongoDB id。 此外,由于它称为_id,因此将自动设置id。

然后是服务层:

@Singleton
@Lock(LockType.READ)
public abstract class ColorService implements InvocationHandler {@JongoCollection("color")@InjectMongoCollection colorMongoCollection;@Insertpublic abstract Color createColor(Color c);@Removepublic abstract int removeAllColors();@FindByIdpublic abstract Color findColorById(String id);@FindOne("{name:#}")public abstract Color findColorByColorName(String colorName);@Find("{r:#}")public abstract Iterable<Color> findColorByRed(int r);public long countColors() {return colorMongoCollection.count();}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {return PersistenceHandler.invoke(colorMongoCollection, method, args);}}

请注意,没有很多代码,但是有些要点确实很有趣。 让我们对其进行分析。

@Singleton用于将EJB定义为单例,它也与@Stateless一起使用,对于Java EE用户而言,这里没有消息。

该类是抽象的。 为什么? 因为它允许我们不实现所有方法,而是定义它们。

还实现java.lang.reflect.InvocationHandler 。 这是因为我们要使用一个非常有趣的功能,该功能允许我们创建一个称为invoke的后备方法。 对于已定义但未实现的任何方法,都会调用此方法。

我们有一个MongoCollection类(来自Jongo项目),已将其注入。 MongoCollection代表MongoDB中的集合。 因为我们需要设置要使用的集合,所以将创建一个名为@JongoCollection的注释,以便您可以传递后端集合的名称。 请注意, MongoCollection是由CDI容器使用我们的自定义生成器生成的。 对于CDI用户,这里也没有消息。

@ApplicationScoped
public class MongoCollectionProducer {@InjectDB mongoDb;Jongo jongo;@PostConstructpublic void initialize() throws UnknownHostException {jongo = new Jongo(mongoDb);}@Produces@JongoCollectionMongoCollection collection(InjectionPoint injectionPoint) {JongoCollection jongoCollectionAnnotation = Reflection.annotation(injectionPoint.getQualifiers(), JongoCollection.class);if(jongoCollectionAnnotation != null) {String collectionName = jongoCollectionAnnotation.value();return jongo.getCollection(collectionName);}throw new IllegalArgumentException();}}

然后有很多方法代表CRUD操作。 请注意,他们不执行,他们只用@Insert,@find,@Remove注释,...,以设置这是我们要执行的方法的目的。 其中一些(例如查找器或删除器)可以接收要执行的类似于Jongo的查询。 还有一个名为countColors的方法,您可以看到它可以作为自定义方法实现,而不必依赖于invoke方法中实现的逻辑。

最后是invoke方法。 该方法将为所有抽象方法调用,并简单地发送到PersistenceHandler类,该类实际上是针对Jongo的util类,用于执行所需的操作。

就是这么简单,如果您想添加新的抽象操作,则只需在PersistenceHandler类中实现它们即可。

你们中的有些人可能会奇怪,为什么我使用注释而不是使用典型的Spring Data方法(该方法的名称表示操作)。 您也可以实现这种方法,这是在PersistenceHandler类中创建正则表达式的简单问题,而不是带有注释的if / else,但是我更喜欢注释方法。 执行时间更快,更干净,例如,您可以将批注名称从@Find重构为@Buscar (相当于西班牙文),而不必担心是否破坏了某些正则表达式。

最后是测试:

@RunWith(Arquillian.class)
public class ColorTest {private static final String MONGODB_RESOURCE = "<resources>\n" + "    <Resource id=\"mongoUri\" class-name=\"com.mongodb.MongoClientURI\" constructor=\"uri\">\n" + "        uri  mongodb://localhost/test\n" + "    </Resource>\n" + "</resources>";@Deploymentpublic static JavaArchive createDeployment() {JavaArchive javaArchive = ShrinkWrap.create(JavaArchive.class).addPackages(true, Color.class.getPackage()).addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml").addAsManifestResource(new StringAsset(MONGODB_RESOURCE), "resources.xml").merge(getJongoAndMongoDependecies());return javaArchive;}private static JavaArchive getJongoAndMongoDependecies() {JavaArchive[] javaArchives = Maven.configureResolver().loadPomFromFile("pom.xml").resolve("org.mongodb:mongo-java-driver", "org.jongo:jongo").withTransitivity().as(JavaArchive.class);JavaArchive mergedLibraries = ShrinkWrap.create(JavaArchive.class);for (JavaArchive javaArchive : javaArchives) {mergedLibraries.merge(javaArchive);}return mergedLibraries;}@EJBColorService colorService;@Beforepublic void cleanDatabase() {colorService.removeAllColors();}@Testpublic void should_insert_color() {Color color = colorService.createColor(new Color("red", 255, 0, 0));assertThat(color.getId(), notNullValue());assertThat(color.getName(), is("red"));assertThat(color.getR(), is(255));assertThat(color.getB(), is(0));assertThat(color.getG(), is(0));}@Testpublic void should_count_number_of_colors() {colorService.createColor(new Color("red", 255, 0, 0));colorService.createColor(new Color("blue", 0, 0, 255));assertThat(colorService.countColors(), is(2L));}@Testpublic void should_find_colors_by_id() {Color originalColor = colorService.createColor(new Color("red", 255, 0, 0));Color color = colorService.findColorById(originalColor.getId());assertThat(color.getId(), notNullValue());assertThat(color.getName(), is("red"));assertThat(color.getR(), is(255));assertThat(color.getB(), is(0));assertThat(color.getG(), is(0));}@Testpublic void should_find_colors_by_name() {colorService.createColor(new Color("red", 255, 0, 0));Color color = colorService.findColorByColorName("red");assertThat(color.getId(), notNullValue());assertThat(color.getName(), is("red"));assertThat(color.getR(), is(255));assertThat(color.getB(), is(0));assertThat(color.getG(), is(0));}@Testpublic void should_find_colors_by_red() {colorService.createColor(new Color("red", 255, 0, 0));colorService.createColor(new Color("white", 255, 255, 255));Iterable<Color> colorByRed = colorService.findColorByRed(255);assertThat(colorByRed, hasItems(new Color("red", 255, 0, 0), new Color("white", 255, 255, 255)));}}

这是一项Arquillian测试,除一行外没有其他特殊之处:

.addAsManifestResource(新的StringAsset(MONGODB_RESOURCE),“ resources.xml”)

因为我们使用的是Apache TomEE,所以我们使用它必须配置在代码中用作javax.annotation.Resource的元素的方式。

META-INF / resources.xml的内容将是:

<resources> <Resource id="mongoUri" class-name="com.mongodb.MongoClientURI" constructor="uri"> uri  mongodb://localhost/test</Resource>
</resources>

然后在MongoClient生产者中使用来创建要在代码内使用的MongoClient实例。 请注意,我们将@Resource用作任何标准资源,例如DataSource ,但实际上注入了MongoClientURI

@ApplicationScoped
public class MongoDBProducer {@Resource(name = "mongoUri")private MongoClientURI mongoClientURI;private DB db;@PostConstructpublic void init() throws UnknownHostException {MongoClient mongoClient = new MongoClient(mongoClientURI);db =  mongoClient.getDB(mongoClientURI.getDatabase());}@Producespublic DB createDB() {return db;}}

因此,实际上Mongo连接是在META-INF / resources.xml文件中配置的,感谢TomEE,我们可以将其视为任何标准资源。

如果要使用其他应用程序服务器,则可以将此方法更改为它提供的方法,或者,如果需要,可以使用DeltaSpike扩展或您自己的方法。 另外,由于MongoClient数据库是从带有@Produces注释的方法中获取的,因此您可以在代码上的任何位置将其注入,因此,如果需要,可以跳过抽象服务层。

这种方法有什么好处?

首先,它是Java EE解决方案,您可以在不依赖Spring框架或任何其他库的情况下使用它。 您可以实现所需的内容,而不必下载大量的库,而仅仅是为了通过某种对象映射访问MongoDB

就像您可能看到的那样,代码非常简单,并且没有任何魔力,您可以毫无问题地对其进行调试,甚至可以根据需要进行改进或更改。 该代码是您的,正在等待修改。 您是否要使用本机MongoDB对象而不是Jongo ? 没问题,您可以实现它。 而且,层数不多,实际上只有一层( PersistenceHandler ),因此该解决方案的执行速度非常快。

当然,这并不意味着您不能使用Spring Data MongoDB 。 这是一个非常有趣的框架,因此,如果您已经在使用Spring ,请继续进行下去,但是如果您打算使用完整的J ava EE解决方案,请克隆此项目并开始使用MongoDB,而无需进行任何网络研究。关于如何将它们整合在一起的知识。

  • 您可以从https://github.com/lordofthejars/tomee-mongodb-starter-project克隆项目

翻译自: https://www.javacodegeeks.com/2014/09/java-ee-mongodb-with-apache-tomee-and-jongo-starter-project.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362010.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

hdu 3831

神题&#xff0c;经典dp 关键是状态的表示。 f[i][j][k] 原串后i个字符&#xff0c;与目标后j个字符做匹配&#xff0c;在这之前最近一次发生的后缀操作为“置k”&#xff0c;k52时表示不置后缀 转载于:https://www.cnblogs.com/zhaozhe/archive/2011/08/26/2154684.html

1017 A除以B (20 分)

本题要求计算 /&#xff0c;其中 A 是不超过 1000 位的正整数&#xff0c;B 是 1 位正整数。你需要输出商数 Q 和余数 R&#xff0c;使得 ABQR 成立。 输入格式&#xff1a; 输入在一行中依次给出 A 和 B&#xff0c;中间以 1 空格分隔。 输出格式&#xff1a; 在一行中依次输出…

阅读react-redux源码(二) - createConnect、match函数的实现

阅读react-redux源码 - 零阅读react-redux源码 - 一阅读react-redux源码(二) - createConnect、match函数的实现 上一节看了Provider组件的实现&#xff0c;主要做的事情就是通过Context透传了来自redux的store和监听store变化的事件对象Subscription的实例。 本节会深入到co…

一个罐子统治一切:Apache TomEE + Shrinkwrap == JavaEE引导

警告&#xff1a;我不是Spring Boot的专家。 我发现很多事情对此非常有趣&#xff0c;并且当然可以真正改善您的日常工作。 而且&#xff0c;我对Spring Boot没有任何反对&#xff0c;也没有开发或使用它的人。 但是我认为社区高估了该产品。 一年前&#xff0c;我开始收到很多…

iview-admin框架运行步骤

第一步&#xff1a; 前往github下载整个iview-admin框架的全部源码 github地址&#xff1a; https://github.com/iview/iview-admin 第二步&#xff1a; 点击Clone or download绿色按钮。下载整个压缩包 第三步&#xff1a; 解压至D盘&#xff0c;在根目录中按 1、前往github下…

阅读react-redux源码(三) - mapStateToPropsFactories、mapDispatchToPropsFactories和mergePropsFactories

阅读react-redux源码 - 零阅读react-redux源码 - 一阅读react-redux源码(二) - createConnect、match函数的实现阅读react-redux源码(三) - mapStateToPropsFactories、mapDispatchToPropsFactories和mergePropsFactories mapStateToPropsFactories import { wrapMapToPropsC…

Xcode 升级后,常常遇到的遇到的警告、错误,解决方法(转)

从sdk3.2.5升级到sdk 7.1中间废弃了很多的方法&#xff0c;还有一些逻辑关系更加严谨了。1&#xff0c;警告&#xff1a;“xoxoxoxo” is deprecated解决办法&#xff1a;查看xoxoxoxo的这个方法的文档&#xff0c;替换掉这个方法即可。2&#xff0c;警告&#xff1a;Declarat…

.net 垃圾回收学习[How To: Use CLR Profiler][翻译学习]【2】

http://msdn.microsoft.com/zh-cn/library/ms979205 注意&#xff1a;内容可能已经过期了。 注意&#xff1a;CLR Profiler最新版本&#xff1a;http://www.microsoft.com/download/en/details.aspx?id16273 Identifying Common Garbage Collection Issues 可以使用CLR Profil…

JavaOne 2014:会议与合同利益冲突

杜克街咖啡馆&#xff0c;工程师可以在街上进行走廊交谈 。 与签约不兼容 我的第11届JavaOne会议&#xff08;2004年至2014年为11 10 1&#xff09;非常出色。 值得参加此活动并结识社区中所有参与的人。 现在&#xff0c;这里是绅士的&#xff0c;但 。 除了经济上的明显优…

JQuery(三)-- AJAX的深入理解以及JQuery的使用

HTTP HTTP http: 超文本传输协议。特点&#xff1a; 简单、快速、灵活、无状态、无连接 URL&#xff1a; 统一资源定位符。 组成&#xff1a;协议名://主机IP&#xff1a;端口号/项目资源地址&#xff1f;传递参数的键值对#锚点 ①ip地址在同一个网段是唯一的。如果是在公…

阅读react-redux源码(四) - connectAdvanced、wrapWithConnect、ConnectFunction和checkForUpdates

阅读react-redux源码 - 零阅读react-redux源码 - 一阅读react-redux源码(二) - createConnect、match函数的实现阅读react-redux源码(三) - mapStateToPropsFactories、mapDispatchToPropsFactories和mergePropsFactories阅读react-redux源码(四) - connectAdvanced、wrapWithC…

(转)模拟鼠标/键盘

鼠标操作类 using System;namespace Edobnet.Net.Lib{/// <summary>/// Mouse 的摘要说明。/// </summary>public class Mouse{public Mouse(){//// TODO: 在此处添加构造函数逻辑//}internal const byte SM_MOUSEPRESENT 19;internal const byte SM_CMOUSEBUTTON…

c++ 返回 char*

一段在C里经常犯错误的代码 一个类&#xff1a; class C{public:C(){}~C(){}public:string a;string funa(){string tmp "1234";return tmp;}};外部调用类C并使用其成员&#xff1a; C classc;char *test1 classc.a.c_str();printf("%s\n", test1);上述正…

JSF的工作方式和调试方式–可以使用polyglot吗?

JSF不是我们通常认为的那样。 这也是一个调试起来可能有些棘手的框架&#xff0c;尤其是在初次遇到时。 在这篇文章中&#xff0c;让我们继续探讨为什么会出现这种情况&#xff0c;并提供一些JSF调试技术。 我们将讨论以下主题&#xff1a; JSF不是我们经常想到的 JSF调试的难…

React组件实现越级传递属性

如果有这样一个结构&#xff1a;三级嵌套&#xff0c;分别是&#xff1a;一级父组件、二级子组件、三级孙子组件&#xff0c;且前者包含后者&#xff0c;结构如图&#xff1a; 如果把一个属性&#xff0c;比如color&#xff0c;从一级传递给三级&#xff0c;一般做法是使用prop…

尝试Office 2003 VSTO的开发、部署

背景&#xff1a;一年前&#xff0c;某项目需要使用到Excel进行数据录入&#xff0c;考虑到很多用户还是使用XPOffice 2003&#xff0c;所以开发的时候直接使用Excel 2003版本进行VBA开发。也许很多人都会说&#xff0c;Win10都出了&#xff0c;微软的Office都要免费了&#xf…

阅读react-redux源码(五) - connectAdvanced中store改变的事件转发、ref的处理和pure模式的处理

阅读react-redux源码 - 零阅读react-redux源码 - 一阅读react-redux源码(二) - createConnect、match函数的实现阅读react-redux源码(三) - mapStateToPropsFactories、mapDispatchToPropsFactories和mergePropsFactories阅读react-redux源码(四) - connectAdvanced、wrapWithC…

Servlet编程API

一、基本的servlet APIJavaEE关于Servlet的API主要有两个包&#xff1a;javax.servlet和javax.servlet.http。前者主要提供了Web容器能够使用的servlet基本类和接口&#xff0c;后者主要包括和HTTP协议相关的servlet类和接口。对servlet的编程&#xff0c;主要是根据需要&#…

初级开发人员在编写单元测试时常犯的错误

自从我编写第一个单元测试以来已经有10年了。 从那时起&#xff0c;我不记得我已经编写了成千上万的单元测试。 老实说&#xff0c;我在源代码和测试代码之间没有任何区别。 对我来说是同一回事。 测试代码是源代码的一部分。 在过去的3-4年中&#xff0c;我与多个开发团队合作…

OpenDaylight开发hello-world项目之开发工具安装

OpenDaylight开发hello-world项目之开发环境搭建 OpenDaylight开发hello-world项目之开发工具安装 OpenDaylight开发hello-world项目之代码框架搭建 在ODL开发之前&#xff0c;要安装好开发环境。ODL使用java语言开发&#xff0c;所以要安装好java。ODL的代码框架是有maven这个…