一、为什么要使用多数据源
在一些业务复杂的系统中,业务数据存储可能在不同的mongodb库中,此时,可能需要同时读取这两个库里的数据,进行一些逻辑处理,此时需要读取不同的库,为了解决这个问题,采用多数据源操作。
二、多数据源配置
spring boot自动配置了多种操作mongodb的api,这里讲解的是MongoTemplate,具体代码如下
1.添加依赖
<!-- mongoDB --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
2.添加配置
#第一个mongodb配置 spring.data.mongodb.primary.database=barrage #如果有多个地址 则这样写localhost:27017,localhost:27017 中间以逗号隔开 spring.data.mongodb.primary.hostPort=localhost:37017 spring.data.mongodb.primary.password= spring.data.mongodb.primary.username= #第二个mongodb配置 spring.data.mongodb.secondary.database=watch-record spring.data.mongodb.secondary.hostPort=localhost:37017 spring.data.mongodb.secondary.password= spring.data.mongodb.secondary.username=
3.重写java配置
package com.example.multidatasource.config.mongodb; 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 org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.List; /** * 根据配置文件创建MongoDbFactory * @date 2017年10月14日 * */ public abstract class AbstractMongoConfig { // Mongo DB Properties private String hostPort, database, username, password; // private String port; // Setter methods go here.. public String getHostPort() { return hostPort; } public void setHostPort(String hostPort) { this.hostPort = hostPort; } public String getDatabase() { return database; } public void setDatabase(String database) { this.database = database; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public MongoDbFactory mongoDbFactory() throws Exception { List<ServerAddress> seeds = new ArrayList<>(); String[] hostPorts = hostPort.split(","); for(int i = 0 ; i < hostPorts.length;i++){ String[] hps = hostPorts[i].split(":"); ServerAddress serverAddress = new ServerAddress(hps[0], Integer.valueOf(hps[1])); seeds.add(serverAddress); } if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){ return new SimpleMongoDbFactory(new MongoClient(seeds), database); } List<MongoCredential> mongoCredentialList = new ArrayList<>(); mongoCredentialList.add(MongoCredential.createCredential(username, database, password.toCharArray())); return new SimpleMongoDbFactory(new MongoClient(seeds, mongoCredentialList), database); } abstract public MongoTemplate getMongoTemplate() throws Exception; }
从代码中可以看到,从配置文件中读取到相应属性进行解析之后,创建MongoDbFactory对象即可。这里要说的是,如果mongodb没有设置用户名密码,则直接使用new SimpleMongoDbFactory(new MongoClient(seeds), database);连接即可。这里使用的是构造方法是:
public MongoClient(List<ServerAddress> seeds) { this(seeds, (new Builder()).build()); }
如果mongodb设置了用户名密码,则需要使用密码验证,此时使用的MongoClient构造方法是:
public MongoClient(List<ServerAddress> seeds, List<MongoCredential> credentialsList) { this(seeds, credentialsList, (new Builder()).build()); }
MongoClient还提供了一些其他构造方法,感兴趣的可以查看源码
MongoTemplate相关配置如下:
- 第一个mongodb配置
package com.example.multidatasource.config.mongodb; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.mongodb.core.MongoTemplate; @Configuration @ConfigurationProperties(prefix = "spring.data.mongodb.primary") public class PrimaryMongoConfig extends AbstractMongoConfig { @Primary @Override public @Bean(name = "primaryMongoTemplate") MongoTemplate getMongoTemplate() throws Exception { return new MongoTemplate(mongoDbFactory()); } }
这里使用了注解@Primary,此注解表示如果没有指明注入哪个MongoTemplate,优先注入此MongoTemplate
- 第二个MongoTemplate配置
package com.example.multidatasource.config.mongodb; 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; @Configuration @ConfigurationProperties(prefix = "spring.data.mongodb.secondary") public class SecondaryMongoConfig extends AbstractMongoConfig{ @Override public @Bean(name = "secondaryMongoTemplate") MongoTemplate getMongoTemplate() throws Exception { return new MongoTemplate(mongoDbFactory()); } }
4.去除spring boot mongodb自动配置
#去除mongodb自动配置 spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration
到此为止mongodb的多数据源配置就算完成了