mongodb+java_Java EE + MongoDb与Apache TomEE和Jongo Starter项目
mongodb+java
知道MongoDB和Java EE ,但是您不確切地知道如何將它們集成在一起? 您是否閱讀了很多有關該主題的內容,但沒有找到適合該目的的解決方案? 這個入門項目適合您:
您將學習如何以一種時尚的方式使用MongoDB和Java 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
mongodb+java
總結
以上是生活随笔為你收集整理的mongodb+java_Java EE + MongoDb与Apache TomEE和Jongo Starter项目的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 微软发布统一版AI助手Copilot 即
- 下一篇: 候选JEP:记录和密封类型
