实现原理:
Spring Boot中通过依赖spring-boot-starter-data-mongodb
,来实现spring-data-mongodb
的自动配置,我们最终使用MongoDB操作数据库是通过 MongoTemplate类完成,他提供增删改查等方法
从上图可以看出MongoTemplate的连接配置可由MongoDbFactory 生成,从而提供了自定义连接的可能,
实际上,spring-data-mongodb
的自动配置也是如此。
所以,可以创建多个一个MongoDbFactory 来构造不同的MongoTemplate,然后在操作数据库时根据使用场景注入不同的MongoTemplate来使用。
用数据库连接uri 创建 MongoClientURI ,再生成 SimpleMongoDbFactory,最后创建 MongoTemplate即可。
编码要点
首先定义多个数据库的配置,代码对应下边第〇点
然后读取数据库的配置,代码对应下边第一点
读取对应的配置信息并且装配指定的MongoTemplate,第三点
所有文件:
application.yml
MultipleMongoProperties
PrimaryMongoConfig
SecondaryMongoConfig
MultipleMongoConfig
PersonTest
MongoTestC
mongodb:
primary:
host: 192.168.1.2
port: 27017
database: primary
#username: admin
#password: admin
secondary:
host: 192.168.1.3
port: 27017
database: secondary
#username: admin
#password: admin
平时单个数据库配置格式为:spring:data:mongodb:... 是因为spring boot 默认的资源加载格式。这里mongodb开头是自定义。没有这个疑问的伙伴可以忽略这段话。。。
通过@ConfigurationProperties(prefix = "mongodb")读取配置文件的mongodb节点配置
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @ClassName: MultipleMongoProperties
* @Description: 从配置文件加载数据源
* @Author Tan
* @Date 2019/7/3
*/
@Component
@ConfigurationProperties(prefix = "mongodb")
public class MultipleMongoProperties {
private MongoProperties primary = new MongoProperties();
private MongoProperties secondary = new MongoProperties();
public MongoProperties getPrimary() {
return primary;
}
public void setPrimary(MongoProperties primary) {
this.primary = primary;
}
public MongoProperties getSecondary() {
return secondary;
}
public void setSecondary(MongoProperties secondary) {
this.secondary = secondary;
}
}
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
/**
* @ClassName: PrimaryMongoConfig
* @Description: TODO
* @Author Tan
* @Date 2019/7/3
*/
@Configuration
@EnableMongoRepositories(mongoTemplateRef = PrimaryMongoConfig.MONGO_TEMPLATE)
public class PrimaryMongoConfig {
public static final String MONGO_TEMPLATE = "primaryMongoTemplate";
}
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
/**
* @ClassName: PrimaryMongoConfig
* @Description: TODO
* @Author TanXiongZhan
* @Date 2019/7/3
*/
@Configuration
@EnableMongoRepositories(mongoTemplateRef = SecondaryMongoConfig.MONGO_TEMPLATE)
public class SecondaryMongoConfig {
public static final String MONGO_TEMPLATE = "secondaryMongoTemplate";
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.mongo.MongoProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
/**
* @ClassName: MultipleMongoConfig
* @Description: 读取对应的配置信息并且构造对应的MongoTemplate
* @Author Tan
* @Date 2019/7/3
*/
@Configuration
public class MultipleMongoConfig {
@Autowired
private MultipleMongoProperties mongoProperties;
@Primary
@Bean(name = PrimaryMongoConfig.MONGO_TEMPLATE)
public MongoTemplate primaryMongoTemplate() throws Exception {
return new MongoTemplate(primaryFactory(this.mongoProperties.getPrimary()));
}
@Bean
@Qualifier(SecondaryMongoConfig.MONGO_TEMPLATE)
public MongoTemplate secondaryMongoTemplate() throws Exception {
return new MongoTemplate(secondaryFactory(this.mongoProperties.getSecondary()));
}
@Bean
@Primary
public MongoDbFactory primaryFactory(MongoProperties mongo) throws Exception {
if (StringUtils.isEmpty(mongo.getUsername()) || mongo.getPassword() == null ) {
return new SimpleMongoDbFactory(new MongoClient(mongo.getHost(), mongo.getPort()),
mongo.getDatabase());
} else {
String password = String.valueOf(mongo.getPassword());
String url = "mongodb://" + mongo.getUsername()
+ ":" + password
+ "@" + mongo.getHost() + ":" + mongo.getPort() + "/" + mongo.getDatabase()
+ "?authSource=admin&authMechanism=SCRAM-SHA-1";
return new SimpleMongoDbFactory(new MongoClientURI(url));
}
}
@Bean
public MongoDbFactory secondaryFactory(MongoProperties mongo) throws Exception {
if (StringUtils.isEmpty(mongo.getUsername()) || mongo.getPassword() == null ) {
return new SimpleMongoDbFactory(new MongoClient(mongo.getHost(), mongo.getPort()),
mongo.getDatabase());
} else {
String password = String.valueOf(mongo.getPassword());
String url = "mongodb://" + mongo.getUsername()
+ ":" + password
+ "@" + mongo.getHost() + ":" + mongo.getPort() + "/" + mongo.getDatabase()
+ "?authSource=admin&authMechanism=SCRAM-SHA-1";
return new SimpleMongoDbFactory(new MongoClientURI(url));
}
}
}
说明:@Primary 表明默认加载,假如使用的时候不表明具体的MongoTemplate,则使用@Primary所示的。如
@Autowired
private MongoTemplate mongoTemplate;
则得到的 mongoTemplate 对象就是 primaryMongoTemplate
public class PersonTest {
private Integer id;
private Integer age;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("mongoTest")
public class MongoTestC {
@Resource(name = PrimaryMongoConfig.MONGO_TEMPLATE)
private MongoTemplate primaryMongoTemplate; //第一个库的MongoTemplate
@Resource(name = SecondaryMongoConfig.MONGO_TEMPLATE)
private MongoTemplate secondaryMongoTemplate; //第二个库的MongoTemplate
@Autowired
private MongoTemplate mongoTemplate; //第一个库的MongoTemplate
@GetMapping(value = "/test1")
public void saveTest() throws Exception {
PersonTest mgtest = new PersonTest();
mgtest.setId(8);
mgtest.setAge(88);
mgtest.setName("8888");
primaryMongoTemplate.save(mgtest);
secondaryMongoTemplate.save(mgtest);
}
}