跳到主要内容
版本:5.1.1

连接 MongoDB

Doubao 中英对照 Connecting to MongoDB

使用 MongoDB 和 Spring 时的首要任务之一,是使用 IoC 容器创建一个 MongoClient 对象。主要有两种方式:使用基于 Java 的 Bean 元数据,或使用基于 XML 的 Bean 元数据。

备注

对于不熟悉如何使用基于 Java 的 Bean 元数据(而非基于 XML 的元数据)来配置 Spring 容器的读者,请参阅参考文档中此处的高层介绍,以及此处的详细文档。

注册 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");
}
}

这种方式让您使用标准的 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;
}
}

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

MongoDatabaseFactory 接口​

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

public interface MongoDatabaseFactory {

MongoDatabase getDatabase() throws DataAccessException;

MongoDatabase getDatabase(String dbName) throws DataAccessException;
}

以下各节展示了如何结合使用容器与基于 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"));

// ...
}
}

The code in bold highlights the use of SimpleMongoClientDbFactory and is the only difference between the listing shown in the getting started section. Use SimpleMongoClientDbFactory when choosing com.mongodb.client.MongoClient as the entrypoint of choice.

注册 MongoDatabaseFactory / ReactiveMongoDatabaseFactory​

要向容器注册一个 MongoDatabaseFactory/ ReactiveMongoDatabaseFactory 实例,您编写的代码与上一节中重点介绍的代码非常相似。以下列展示了一个简单示例:

@Configuration
public class MongoConfiguration {

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

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)));
});
}
}

如果您需要在用于创建 SimpleMongoClientDbFactory 的 com.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);
});
}
}