需求
一个项目里需要连接多个 mongodb,有的 mongodb 是集群。
详细步骤及代码
- step1:创建springboot项目,pom.xml引入依赖 mongodb
- spring-boot-starter-parent:2.0.4.RELEASE 版本
- spring-boot-starter-web
- spring-boot-starter-data-mongodb
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.awen</groupId>
<artifactId>day201220-mongodb-connect</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>day201220-mongodb-connect</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mongodb -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- step2:application.yaml 添加mongodb配置
server:
port: 8080
servlet:
context-path: /mongodb-connect
spring:
application:
name: mongodb-connect
# mongodb
data:
mongodb:
test1:
# uri: mongodb://test1:test1_password@127.0.0.1:27017/test1_authsource
addresses: 127.0.0.1:27017
username: test1
password: test1_password
authsource: test1_authsource
database: test1_database
test2:
# uri: mongodb://${mongodb.username}:${mongodb.password}@${mongodb.addresses}/${mongodb.authsource}
addresses: 127.0.0.1:27017,127.0.0.2:27017
username: test2
password: test2_password
authsource: admin
database: test2_database
- step3:创建 AbstractMongoConfig 抽象MongoConfig
- 建议使用 MongoCredential 方式,不推荐 MongoClientURI 方式创建。
- 因为有的时候 mongodb 连接的密码是带 @ 或者其他特殊字符的密码,使用 uri 方式建立连接,可能在拆分 uri 的时候,拆分错误,导致创建失败。
test1 mongodb 的 uri 是:mongodb://test1:test1_password@127.0.0.1:27017/test1_authsource。
比如密码是 test1@123456,如果使用 uri,mongodb://test1:test1@123456@127.0.0.1:27017/test1_authsource,会被拆分为“username=test1, password=test1, addresses=123456@127.0.0.1:27-17”,会创建失败。
package com.awen.day201220mongodbconnect.config;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* MongoTemplate 配置
* 使用 MongoCredential 方式;支持集群。
*/
public abstract class AbstractMongoConfig {
/**
* mongodb 配置信息
*/
private ArrayList<String> addresses;
private String uri;
private String authsource, database, username, password;
// 省略 addresses、uri、authsource, database, username, password 的 setXXX/getXXX方法
// ...
/**
* 获取 MongoTemplate 对象
*/
public abstract MongoTemplate getMongoTemplate() throws Exception;
/**
* 创建 MongoDbFactory 工厂:
* 覆盖容器中默认的 MongoDbFactory Bean
*/
public MongoDbFactory mongoDbFactory() {
// MongoDB 地址列表
List<ServerAddress> serverAddresses = new ArrayList<ServerAddress>();
for (String address : addresses) {
String[] hostAndPort = address.split(":");
String host = hostAndPort[0];
Integer port = Integer.parseInt(hostAndPort[1]);
ServerAddress serverAddress = new ServerAddress(host, port);
serverAddresses.add(serverAddress);
}
// 创建非认证客户端
// MongoClient mongoClient = new MongoClient(serverAddresses);
// 使用 MongoClientURI 方式创建
// MongoClient mongoClient = new MongoClient(new MongoClientURI(uri));
// 使用 MongoCredential 方式创建
// 连接认证
MongoCredential mongoCredential = MongoCredential.createCredential(username, authsource, password.toCharArray());
// 创建认证客户端
MongoClient mongoClient = new MongoClient(serverAddresses, Arrays.asList(mongoCredential));
// 创建MongoDbFactory
MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClient, database);
return mongoDbFactory;
}
}
- step4:创建 MongoDBTest1Config,继承 AbstractMongoConfig 类
package com.awen.day201220mongodbconnect.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
/**
* test1 MongoTemplate 配置
*/
@Configuration
@ConfigurationProperties(prefix = "spring.data.mongodb.test1")
public class MongoDBTest1Config extends AbstractMongoConfig {
@Override
@Bean(name = "test1MongoTemplate")
public MongoTemplate getMongoTemplate() throws Exception {
return new MongoTemplate(mongoDbFactory());
}
}
- step5:创建 MongoDBTest2Config,继承 AbstractMongoConfig 类
package com.awen.day201220mongodbconnect.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;
/**
* test2 MongoTemplate 配置
*/
@Configuration
@ConfigurationProperties(prefix = "spring.data.mongodb.test2")
public class MongoDBTest2Config extends AbstractMongoConfig {
@Override
@Bean(name = "test2MongoTemplate")
public MongoTemplate getMongoTemplate() throws Exception {
return new MongoTemplate(mongoDbFactory());
}
}
- step6:添加 Controller 类 测试
package com.awen.day201220mongodbconnect.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.*;
/**
* 测试 mongodb 查询
*/
@RestController
@RequestMapping("test")
public class MongoTestController {
private final static Logger logger = LoggerFactory.getLogger(MongoTestController.class);
@Resource
@Qualifier("test1MongoTemplate")
MongoTemplate test1MongoTemplate;
@Resource
@Qualifier("test2MongoTemplate")
MongoTemplate test2MongoTemplate;
@GetMapping("query1")
public List<Map> queryTest1() {
List<Map> userList = test1MongoTemplate.findAll(Map.class, "user");
return userList;
}
}
- step7:启动类添加注解
- 去掉 mongodb 自动配置:@SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
- 经测试,不加 (exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class}) 也可以启动成功,且可以访问。
package com.awen.day201220mongodbconnect;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
// 去掉 mongodb 的自动配置
@SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
public class Day201220MongodbConnectApplication {
public static void main(String[] args) {
SpringApplication.run(Day201220MongodbConnectApplication.class, args);
}
}
- step8:测试
访问 http://127.0.0.1:8080/mongodb-connect/test/query1
返回结果:[{"_id":{“timestamp”:1608460199,“machineIdentifier”:300955,“processIdentifier”:7148,“counter”:4866,“time”:1608460199000,“date”:“2020-12-20T10:29:59.000+0000”,“timeSecond”:1608460199},“username”:“awen”,“age”:18.0}]