In the application, a single MongoClient
object with a required number of connections, using connection pooling, will work in this case. The default value of the connection pool of 100
, and can be modified (or configured) as needed.
The mongo client object can be created at the start of the application and is closed only when the application is closed. This saves the resources related to creating a connection with the mongo client objects in each collection access class.
The same mongo client object can be used throughout the application. A singleton class (which maintains one instance of the mongo client object) can be accessed by any other object in the application which needs a connection to the MongoDB database server.
What is connection pooling?
In software engineering, a connection pool is a cache of database
connections maintained so that the connections can be reused when
future requests to the database are required. Connection pools are
used to enhance the performance of executing commands on a database.
Opening and maintaining a database connection for each user,
especially requests made to a dynamic database-driven website
application, is costly and wastes resources. In connection pooling,
after a connection is created, it is placed in the pool and it is used
again so that a new connection does not have to be established. If all
the connections are being used, a new connection is made and is added
to the pool. Connection pooling also cuts down on the amount of time a
user must wait to establish a connection to the database.
Example Code:
/*
* Manages the MongoClient object and its settings like host, port, connection pool, etc.
*/
public class DBAccess {
private static MongoClient mongoClient;
private static DBAccess dbAccess;
// MongoClient with default settings
// NOTE: the code will have only one of the constructors
//private DBAccess() {
// final String connectionString = "mongodb://localhost:27017";
// this.mongoClient = MongoClients.create(connectionString);
//}
// MongoClient with custom settings.
// Private constructor, so that the class can be instantiated outside this class.
// NOTE: the code will have only one of the constructors
private DBAccess() {
MongoClientSettings settings =
MongoClientSettings.builder()
.applyToConnectionPoolSettings(builder ->
builder.maxSize(40).minSize(10))
.applyToClusterSettings(builder ->
builder.hosts(Arrays.asList(new ServerAddress("localhost", 27017))))
.build();
mongoClient = MongoClients.create(settings);
}
public static MongoClient getConnection() {
if (dbAccess == null) {
dbAccess = new DBAccess();
}
return mongoClient;
}
public static void closeDatabase() {
mongoClient.close();
}
}
/*
* Class manages a collection.
*/
public class CollectionOneAccess {
public static String COLLECTION_ONE = "collection_one";
private MongoCollection<Document> collection;
public CollectionOneAccess(MongoDatabase db) {
collection = db.getCollection(COLLECTION_ONE);
}
public void printOneDocument() {
Document myDoc = collection.find().first();
System.out.println(myDoc.toJson());
}
// other CRUD operations ...
}
// Usage of DBAcess and CollectionOneAccess classes:
private static final String APP_DATABASE = "abc_db";
public static void main(String [] args) {
MongoDatabase database = DBAccess.getConnection().getDatabase(APP_DATABASE);
CollectionOneAccess one = new CollectionOneAccess(database);
one.printOneDocument();
// ...
}
Mongo Client
MongoClient
object is used to connect to the MongoDB server, get access to a database using the getDatebase()
method and work with collections.
com.mongodb.client.MongoClient
interface:
A client-side representation of a MongoDB cluster. Instances can
represent either a standalone MongoDB instance, a replica set, or a
sharded cluster. Instance of this class are responsible for
maintaining an up-to-date state of the cluster, and possibly cache
resources related to this, including background threads for
monitoring, and connection pools.
From the MongoDB Java documentation:
The MongoClient instance represents a pool of connections to the database; you will only need one instance of class MongoClient even with multiple threads.
IMPORTANT: Typically you only create one MongoClient instance for a
given MongoDB deployment (e.g. standalone, replica set, or a sharded
cluster) and use it across your application. However, if you do create
multiple instances:
- All resource usage limits (e.g. max connections, etc.) apply per MongoClient instance.
- To dispose of an instance, call MongoClient.close() to clean up resources.
The following code creates a MongoDB client connection object with default settings, like the host ("localhost") and port (27017
), connection pooling, etc., and connects to a MongoDB instance and gets access to the testDB
database.
MongoClient mongoClient = MongoClients.create();
MongoDatabase database = mongoClient.getDatabase("testDB");
Mongo Client Settings:
You can explicitly specify other settings with the MongoClientSettings
to control the behavior of a MongoClient
.
MongoClient mongoClient = MongoClients.create(MongoClientSettings settings)
The ConnectionPoolSettings
object specifies all settings that relate to the pool of connections to a MongoDB server. The application creates this connection pool when the client object is created. ConnectionPoolSettings.Builder
is a builder for ConnectionPoolSettings
, has methods to specify the connection pool properties. E.g., maxSize(int maxSize)
: The maximum number of connections allowed (default is 100
). Other methods include, minSize
, maxConnectionIdleTime
, etc.
Code to instantiate a MongoClient
with connection pool settings:
MongoClientSettings settings = MongoClientSettings.builder()
.applyToConnectionPoolSettings(builder ->
builder.maxSize(20))
.build();
MongoClient mongoClient = MongoClients.create(settings);
// ...
// Verify the connection pool settings
System.out.println("Pool size: " +
settings.getConnectionPoolSettings().getMaxSize());