跳到主要内容

连接到 MongoDB

DeepSeek V3 中英对照 Connecting to MongoDB

在使用 MongoDB 和 Spring 时,首要任务之一是使用 IoC 容器创建 MongoClient 对象。有两种主要方式可以实现这一点,一是使用基于 Java 的 bean 元数据,二是使用基于 XML 的 bean 元数据。

备注

对于那些不熟悉如何使用基于 Java 的 bean 元数据来配置 Spring 容器而不是基于 XML 的元数据的用户,请参阅参考文档中的高级介绍此处以及详细文档此处

注册 Mongo 实例

以下示例展示了如何注册一个 MongoClient 实例:

@Configuration
public class AppConfig {

/*
* Use the standard Mongo driver API to create a com.mongodb.client.MongoClient instance.
*/
public @Bean com.mongodb.client.MongoClient mongoClient() {
return com.mongodb.client.MongoClients.create("mongodb://localhost:27017");
}
}
java

这种方法允许你使用标准的 MongoClient 实例,容器则使用 Spring 的 MongoClientFactoryBean/ReactiveMongoClientFactoryBean。与直接实例化 MongoClient 相比,FactoryBean 还有一个额外的优势,即它为容器提供了一个 ExceptionTranslator 实现,该实现将 MongoDB 异常转换为 Spring 的可移植 DataAccessException 层次结构中的异常,适用于使用 @Repository 注解的数据访问类。该层次结构及 @Repository 的使用在 Spring 的 DAO 支持功能 中有详细描述。

以下示例展示了一个基于 Java 的 bean 元数据示例,该元数据支持在带有 @Repository 注解的类上进行异常转换:

@Configuration
public class AppConfig {

/*
* Factory bean that creates the com.mongodb.client.MongoClient instance
*/
public @Bean MongoClientFactoryBean mongo() {
MongoClientFactoryBean mongo = new MongoClientFactoryBean();
mongo.setHost("localhost");
return mongo;
}
}
java

要访问由 FactoryBean 创建的 MongoClient 对象,你可以在其他 @Configuration 类或你自己的类中使用 private @Autowired MongoClient mongoClient; 字段。

MongoDatabaseFactory 接口

MongoClient 是 MongoDB 驱动 API 的入口点,但要连接到特定的 MongoDB 数据库实例,还需要额外的信息,例如数据库名称以及可选的用户名和密码。有了这些信息,你可以获取一个 MongoDatabase 对象,并访问特定 MongoDB 数据库实例的所有功能。Spring 提供了 org.springframework.data.mongodb.core.MongoDatabaseFactoryorg.springframework.data.mongodb.core.ReactiveMongoDatabaseFactory 接口,如下所示,用于引导与数据库的连接:

public interface MongoDatabaseFactory {

MongoDatabase getDatabase() throws DataAccessException;

MongoDatabase getDatabase(String dbName) throws DataAccessException;
}
java

以下部分展示了如何使用基于 Java 或 XML 的元数据来配置 MongoDatabaseFactory 接口的实例。接着,你可以使用 MongoDatabaseFactory / ReactiveMongoDatabaseFactory 实例来配置 MongoTemplate / ReactiveMongoTemplate

与使用 IoC 容器来创建模板实例不同,你可以在标准的 Java 代码中使用它们,如下所示:

public class MongoApplication {

public static void main(String[] args) throws Exception {

MongoOperations mongoOps = new MongoTemplate(new SimpleMongoClientDatabaseFactory(MongoClients.create(), "database"));

// ...
}
}
java

加粗的代码强调了 SimpleMongoClientDbFactory 的使用,这也是与入门部分中展示的代码唯一的区别。当选择 com.mongodb.client.MongoClient 作为入口点时,请使用 SimpleMongoClientDbFactory

注册 MongoDatabaseFactory / ReactiveMongoDatabaseFactory

要在容器中注册一个 MongoDatabaseFactory/ReactiveMongoDatabaseFactory 实例,你可以编写类似于前一节中突出显示的代码。以下清单展示了一个简单的示例:

@Configuration
public class MongoConfiguration {

@Bean
public MongoDatabaseFactory mongoDatabaseFactory() {
return new SimpleMongoClientDatabaseFactory(MongoClients.create(), "database");
}
}
java

MongoDB Server 第 3 代在连接到数据库时更改了认证模型。因此,一些可用于认证的配置选项不再有效。你应该使用 MongoClient 特定的选项,通过 MongoCredential 来设置凭据并提供认证数据,如下例所示:

@Configuration
public class MongoAppConfig extends AbstractMongoClientConfiguration {

@Override
public String getDatabaseName() {
return "database";
}

@Override
protected void configureClientSettings(Builder builder) {

builder
.credential(MongoCredential.createCredential("name", "db", "pwd".toCharArray()))
.applyToClusterSettings(settings -> {
settings.hosts(singletonList(new ServerAddress("127.0.0.1", 27017)));
});
}
}
java

如果你需要在用于创建 SimpleMongoClientDbFactorycom.mongodb.client.MongoClient 实例上配置额外的选项,你可以参考一个现有的 bean,如下例所示。为了展示另一种常见的使用模式,下面的代码清单展示了如何使用属性占位符,这允许你参数化配置以及 MongoTemplate 的创建:

@Configuration
@PropertySource("classpath:/com/myapp/mongodb/config/mongo.properties")
public class MongoAppConfig extends AbstractMongoClientConfiguration {

@Autowired
Environment env;

@Override
public String getDatabaseName() {
return "database";
}

@Override
protected void configureClientSettings(Builder builder) {

builder.applyToClusterSettings(settings -> {
settings.hosts(singletonList(
new ServerAddress(env.getProperty("mongo.host"), env.getProperty("mongo.port", Integer.class))));
});

builder.applyToConnectionPoolSettings(settings -> {

settings.maxConnectionLifeTime(env.getProperty("mongo.pool-max-life-time", Integer.class), TimeUnit.MILLISECONDS)
.minSize(env.getProperty("mongo.pool-min-size", Integer.class))
.maxSize(env.getProperty("mongo.pool-max-size", Integer.class))
.maintenanceFrequency(10, TimeUnit.MILLISECONDS)
.maintenanceInitialDelay(11, TimeUnit.MILLISECONDS)
.maxConnectionIdleTime(30, TimeUnit.SECONDS)
.maxWaitTime(15, TimeUnit.MILLISECONDS);
});
}
}
java