1.Mongo和MongoClient的關系
MongoClient繼承自Mongo,使用Mongo也可建立連接,但是需要使用與Mongo適應的MongoOptions,MongoURI等類型。
2.建立連接
在MongoDB Java Driver API中,要操作MongoDB的第一步和使用其他DB Java Driver類似,都需要首先和數據庫建立連接。在MongoDBJava Driver API中,建立連接的類為com.mongodb.MongoClient.在討論連接字符串等內容之前,我們來看看它最簡單的使用方式:
MongoClient client = new MongoClient();
一個構造函數不帶任何參數的版本。使用這個構造函數連接到的是本地的MongoDB服務,即/127.0.0.1:27017,當然你如果改變了MongoDB服務的端口,那么這里顯示的端口就是你的端口了。
可以通過以下單元測試代碼進行驗證:
@Test public void testConstruactors() throws UnknownHostException { MongoClient client; client = new MongoClient(); //也可指定連接的Host: //client = new MongoClient("127.0.0.1"); assertEquals(new ServerAddress(), client.getAddress()); client.close(); }
MongoClientOptions customClientOptions = new MongoClientOptions.Builder().connectionsPerHost(100).build();
分析上面的代碼,MongoClientOptions.Builder()得到的是一個MongoClientOptions的Builder,通過該Builder可以設置各種Options,例如connectionsPerHost(100),設置連接池中最大連接個數,需要注意的是,每個屬性的設置方法的返回類型是一個Builder,這意味着可以采用類似下面的鏈式調用
MongoClientOptions customClientOptions = new MongoClientOptions.Builder().connectionsPerHost(100).threadsAllowedToBlockForConnectionMultiplier(200).build();
MongoClientOptions customClientOptions = new MongoClientOptions.Builder().connectionsPerHost(50).maxWaitTime(2000).build(); MongoOptions options = new MongoOptions(customClientOptions); client = new MongoClient("127.0.0.1", customClientOptions); // 每個MongoClient實例維護一個連接池 assertEquals(new ServerAddress("127.0.0.1"), client.getAddress()); assertEquals(options, client.getMongoOptions()); client.close();
MongoOptions options=new MongoOptions(customClientOptions):這行代碼並不影響MongoClientOptions的使用,只是展示如何獲取到設置的MongoClientOptions。
此外,也可直接通過MongoClient.getMongoOptions()獲取到MongoOptions后,進行設置,而不使用MongoClientOptions,如下
MongoOptions mps = mongoClient.getMongoOptions();
mps.setConnectionsPerHost(mongoDBConfig.getPoolSize());
mps.setConnectTimeout(mongoDBConfig.getConnectTimeout());
mps.setMaxWaitTime(mongoDBConfig.getMaxWaitTime());
通過兩種方式的對比,我更喜歡MongoClientOptions,代碼更加優雅。另外,即使沒有設置MongoClientOptions,MongoClient也會有默認的設置。
最簡單的連接字符串就是:mongodb://127.0.0.1
當然,在真正在項目開發中,沒人會這么用!!!!!!~~~回到主題,在MongoClient中,如何使用連接字符串進行連接呢?MongoDB Java Driver提供了一個 com.mongodb.MongoClientURI類型,使用方式如下:
client = new MongoClient(new MongoClientURI("mongodb://kwiner:test123@127.0.0.1/test?authMechanism=MONGODB-CR&maxPoolSize=500")); client.close();
5.安全連接方式
MongoClient也提供了用戶名和密碼連接到指定數據庫的方式,需要用到com.mongodb.MongoCredential,該類在mongo-java-driver的2.11.0版本中才開始提供,請注意!
MongoClientOptions clientOptions=new MongoClientOptions.Builder().connectionsPerHost(poolSize).threadsAllowedToBlockForConnectionMultiplier(200).build(); List<MongoCredential> lstCredentials = Arrays.asList(MongoCredential.createMongoCRCredential("admin", "myinfo", "123456".toCharArray())); client = new MongoClient(new ServerAddress("127.0.0.1"),lstCredentials, clientOptions); client.close(); 或者 MongoClientOptions mongoOptions=new MongoClientOptions.Builder().connectionsPerHost(poolSize).threadsAllowedToBlockForConnectionMultiplier(200).build(); MongoClient mongoClient = new MongoClient(new ServerAddress(server, port), mongoOptions); // 每個MongoClient實例維護一個連接池
try { db = mongoClient.getDatabase(database); collection = db.getCollection(table); catch (Exception e) { mongoClient.close(); throw e; }
MongoClientOptions.Builder builder = new MongoClientOptions.Builder(); MongoClientOptions options = builder.build(); assertEquals(100, options.getConnectionsPerHost());//最大連接數 assertEquals(0, options.getMinConnectionsPerHost());//最小連接數 assertEquals(0, options.getMaxConnectionIdleTime());//連接的最大閑置時間 assertEquals(0, options.getMaxConnectionLifeTime());//連接的最大生存時間 assertEquals(120000, options.getMaxWaitTime());//最大等待可用連接的時間 assertEquals(10000, options.getConnectTimeout());//連接超時時間 MongoClient client = new MongoClient("127.0.0.1", customClientOptions); client.close();
7.連接副本集
使用MongoDB作為數據庫,基本上都會使用副本集,在這個集里面,有primary節點,又有其他secondary節點,並使用了讀寫分離,這個時候,使用java連接MongoDB服務應該怎么做呢? 其實很簡單,就是使用一個ServerAddress集合保存副本集中的所有節點,然后作為MongoClient的構造函數的參數,並使用ReadPreference設置讀寫策略,注意,ReadPreference的讀寫策略既可以在MongoClient上設置,作用與使用MongoClient連接的所有操作,也可以設置到每次具體的集合操作上,作用域該次操作。代碼如下:
在MongoClient上設置讀寫策略:
List<ServerAddress> addresses = new ArrayList<ServerAddress>(); ServerAddress address1 = new ServerAddress("192.168.1.136" , 27017); ServerAddress address2 = new ServerAddress("192.168.1.137" , 27017); ServerAddress address3 = new ServerAddress("192.168.1.138" , 27017); addresses.add(address1); addresses.add(address2); addresses.add(address3); mongoClient = new MongoClient(lstAddrs); mongoClient.setReadPreference(ReadPreference.primary());
在某次操作上設置讀寫策略:
List<ServerAddress> addresses = new ArrayList<ServerAddress>(); ServerAddress address1 = new ServerAddress("192.168.1.136" , 27017); ServerAddress address2 = new ServerAddress("192.168.1.137" , 27017); ServerAddress address3 = new ServerAddress("192.168.1.138" , 27017); addresses.add(address1); addresses.add(address2); addresses.add(address3); MongoClient client = new MongoClient(addresses); DB db = client.getDB( "test" ); DBCollection coll = db.getCollection( "test" ); BasicDBObject object = new BasicDBObject(); object.append( "test2" , "testval2" ); //讀操作從副本節點讀取 ReadPreference preference = ReadPreference.secondary(); DBObject dbObject = coll.findOne(object, null , preference); System.out.println(dbObject);
8.mongo連接池屬性設置
Mongo的實例其實就是一個數據庫連接池,這個連接池里默認有10個鏈接。我們沒有必要重新實現這個鏈接池,但是我們可以更改這個連接池的配置。因為Mongo的實例就是一個連接池,所以,項目中最好只存在一個Mongo的實例。
常見的配置參數:
connectionsPerHost:每個主機的連接數
threadsAllowedToBlockForConnectionMultiplier:線程隊列數,它以上面connectionsPerHost值相乘的結果就是線程隊列最大值。如果連接線程排滿了隊列就會拋出“Out of semaphores to get db”錯誤。
maxWaitTime:最大等待連接的線程阻塞時間
connectTimeout:連接超時的毫秒。0是默認和無限
socketTimeout:socket超時。0是默認和無限
autoConnectRetry:這個控制是否在一個連接時,系統會自動重試
還有許多配置,可以參見mongodb的API。
