如何从Java EE无状态应用程序连接到MongoDB
在本文中,我將介紹如何從無狀態Java EE應用程序連接到MongoDB,以利用與MongoDB Java驅動程序提供的數據庫的內置連接池。 如果您開發的REST API對MongoDB執行操作,則可能是這種情況。
獲取Java MongoDb驅動程序
要將Java連接到MongoDB,可以使用Java MongoDB Driver 。 如果使用Maven構建應用程序,則可以將依賴項添加到pom.xml文件中:
MongoDB Java驅動程序依賴性
org.mongodbmongo-java-driver2.12.3該驅動程序為MongoDB客戶端(com.mongodb.MongoClient)提供了內部池。 MongoClient類被設計為線程安全的并在線程之間共享。 對于大多數應用程序,整個JVM應該具有一個MongoClient安裝。 因此,您不希望在Java EE無狀態應用程序中為每個請求創建一個新的MongoClient實例。
實現一個@Singleton EJB
一個簡單的解決方案是使用@Singleton EJB來保存MongoClient:
Singleton持有MongoClient
package org.codingpedia.demo.mongoconnection;import java.net.UnknownHostException;import javax.annotation.PostConstruct; import javax.ejb.ConcurrencyManagement; import javax.ejb.ConcurrencyManagementType; import javax.ejb.Lock; import javax.ejb.LockType; import javax.ejb.Singleton;import com.mongodb.MongoClient;@Singleton @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER) public class MongoClientProvider {private MongoClient mongoClient = null;@Lock(LockType.READ)public MongoClient getMongoClient(){ return mongoClient;}@PostConstructpublic void init() {String mongoIpAddress = "x.x.x.x";Integer mongoPort = 11000;try {mongoClient = new MongoClient(mongoIpAddress, mongoPort);} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} }}注意:
- @Singleton –可能是此類中最重要的代碼行。 此注釋指定在應用程序中將僅存在一個這種類型的bean的單例。 該bean可以由多個線程同時調用。 它還帶有@PostConstruct批注。 此注釋用于需要依賴注入完成后才能執行任何初始化的方法上(在我們的情況下是初始化MongoClient)
- @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)聲明單例會話bean的并發管理類型。 默認情況下,它設置為Container,在這里我僅用它來突出顯示它的存在。 另一個選項ConcurrencyManagementType.BEAN指定Bean開發人員負責管理對Bean實例的并發訪問。
- @Lock(LockType.READ)指定具有容器管理的并發性的單例bean的并發鎖定類型。 當設置為LockType.READ ,它將強制執行該方法以允許對其進行完全并發訪問(假定未持有任何寫鎖)。 這允許多個線程訪問相同的MongoClient實例,并利用與數據庫的內部連接池。 這非常重要,因為另一個更保守的選項@Lock(LockType.WRITE)是DEFAULT,并強制對bean實例的獨占訪問。 這應該在高度并發的環境中使方法變慢。
使用@Singleton EJB
現在您已經在應用程序中“保留了” MongoClient,您可以注入MongoClientProvider來訪問MongoDB(例如,獲取集合名稱):
從其他bean示例訪問MongoClient
package org.codingpedia.demo.mongoconnection;import java.util.Set;import javax.ejb.EJB; import javax.ejb.Stateless;import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBObject; import com.mongodb.MongoClient; import com.mongodb.util.JSON;@Stateless public class TestMongoClientProvider {@EJBMongoClientProvider mongoClientProvider;public Set<String> getCollectionNames(){MongoClient mongoClient = mongoClientProvider.getMongoClient();DB db = mongoClient.getDB("myMongoDB"); Set<String> colls = db.getCollectionNames();for (String s : colls) {System.out.println(s);} return colls;}}注意: db對象將是到指定數據庫的MongoDB服務器的連接。 有了它,您可以進行進一步的操作。 我鼓勵您閱讀有關Java驅動程序入門的更多信息……
意識到
要記住的一方面:
“對于對數據庫的每個請求(查找,插入等),Java線程都會從池中獲取一個連接,執行該操作,然后釋放該連接。 這意味著每次使用的連接(插座)可能不同。
此外,如果啟用了slaveOk選項的副本集,則讀取操作將在所有從屬設備之間平均分配。 這意味著在同一個線程中,寫入和讀取之后的數據可能會發送到不同的服務器(主服務器然后是從服務器)。 反過來,由于復制是異步的,因此讀取操作可能看不到剛剛寫入的數據。 如果要確保“會話”(也許是http請求)中的完全一致性,則希望驅動程序使用相同的套接字,這可以通過使用“一致請求”來實現。 在操作之前調用requestStart(),然后調用requestDone()將連接釋放回池:
確保完整的一致性
DB db...; db.requestStart(); try {db.requestEnsureConnection();code.... } finally {db.requestDone(); }DB和DBCollection是完全線程安全的。 實際上,它們被緩存了,因此無論如何您都可以得到相同的實例。” [3]
資源資源
翻譯自: https://www.javacodegeeks.com/2014/10/how-to-connect-to-mongodb-from-a-java-ee-stateless-application.html
總結
以上是生活随笔為你收集整理的如何从Java EE无状态应用程序连接到MongoDB的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓性能测试工具都有哪些(安卓性能测试工
- 下一篇: 具有Spring Boot和Java配置