Reputation: 31
I am developing a Java Restful web application and planning to use MongoDB with Morphia as ODM . As I am new to MongoDB, I needed a few suggestions.
The best way to handle db connections is to make use of db connection pool, which mongoClient takes care of.
Morphia morphia = new Morphia();
ServerAddress addr = new ServerAddress("127.0.0.1", 27017);
String databaseName = "test";
MongoClient mongoClient = new MongoClient(addr);
Datastore datastore = morphia.createDatastore(mongoClient, databaseName);
So I need to reuse the above datastore and not create a new instance upon every request as it can waste a lot of resources and affect performance. Should I be implementing the above as singleton class? Can someone help me through this?
Upvotes: 1
Views: 3880
Reputation: 21
Check out the config in this demo github.com/xeraa/morphia-demo
/**
* MongoDB providing the database connection for main.
*/
public class MongoDB {
public static final String DB_HOST = "127.0.0.1";
public static final int DB_PORT = 27017;
public static final String DB_NAME = "morphia_demo";
private static final Logger LOG = Logger.getLogger(MongoDB.class.getName());
private static final MongoDB INSTANCE = new MongoDB();
private final Datastore datastore;
private MongoDB() {
MongoClientOptions mongoOptions = MongoClientOptions.builder()
.socketTimeout(60000) // Wait 1m for a query to finish, https://jira.mongodb.org/browse/JAVA-1076
.connectTimeout(15000) // Try the initial connection for 15s, http://blog.mongolab.com/2013/10/do-you-want-a-timeout/
.maxConnectionIdleTime(600000) // Keep idle connections for 10m, so we discard failed connections quickly
.readPreference(ReadPreference.primaryPreferred()) // Read from the primary, if not available use a secondary
.build();
MongoClient mongoClient;
mongoClient = new MongoClient(new ServerAddress(DB_HOST, DB_PORT), mongoOptions);
mongoClient.setWriteConcern(WriteConcern.SAFE);
datastore = new Morphia().mapPackage(BaseEntity.class.getPackage().getName())
.createDatastore(mongoClient, DB_NAME);
datastore.ensureIndexes();
datastore.ensureCaps();
LOG.info("Connection to database '" + DB_HOST + ":" + DB_PORT + "/" + DB_NAME + "' initialized");
}
public static MongoDB instance() {
return INSTANCE;
}
// Creating the mongo connection is expensive - (re)use a singleton for performance reasons.
// Both the underlying Java driver and Datastore are thread safe.
public Datastore getDatabase() {
return datastore;
}
}
Upvotes: 2
Reputation: 127
you can like this:
private MongoClient mongoClient = null;
private String mongoUrl="xxxx";//You can also use spring injection,@Value(value = "${db.mongo.url}")
private static final Morphia MORPHIA = new Morphia();
public Datastore getMORPHIADB(String dbName) {
if (mongoClient == null) {
//初始化
init();
}
return MORPHIA.createDatastore(mongoClient, dbName);
}
@PostConstruct
public void init() {
try {
//此处其它参数我们不做配置,采用默认配置MongoClientOptions.Builder里面配置连接池的参数
MongoClientOptions.Builder options = new MongoClientOptions.Builder()
.connectionsPerHost(30); //连接池大小(默认初始化为100个,原来老版本是10个)
MongoClientURI mongoClientURI = new MongoClientURI(mongoUrl, options);
mongoClient = new MongoClient(mongoClientURI);
} catch (MongoClientException e) {
LOGGER.error("建立MongoClient异常");
}
}
@PreDestroy
public synchronized void closeConnection() {
if (mongoClient != null) {
mongoClient.close();
}
}
when need use, you can like this: private Datastore datastore = mongoConnService.getMORPHIADB("xxx");
Upvotes: -1