如何配置SpringBoot下的Mongodb多数据源呢?
1. 配置 application 属性
例如 yml 配置,配置多个数据源,如下面:
spring:
data:
db1:
user: <username>
password: <password>
hosts: www.abc.com
database: demo1
options: authSource=admin&maxPoolSize=10&minPoolSize=2&connectTimeoutMS=600000&socketTimeoutMS=600000&authMechanism=SCRAM-SHA-256&tls=true
db2:
user: <username>
password: <password>
hosts: www.abc.com
database: demo1
options: authSource=admin&maxPoolSize=10&minPoolSize=2&connectTimeoutMS=600000&socketTimeoutMS=600000&authMechanism=SCRAM-SHA-256&tls=true
db3:
user: <username>
password: <password>
hosts: www.abc.com
database: demo1
options: authSource=admin&maxPoolSize=10&minPoolSize=2&connectTimeoutMS=600000&socketTimeoutMS=600000&authMechanism=SCRAM-SHA-256&tls=true
2. 创建Spring Config配置
例如在项目源代码的 config 目录下,新建三个配置 java 代码文件:
MongoConfiguration.java是主要的配置文件,里面指明了Spring注入时组件用哪个bean,且对应bean用哪个数据源。
MongoConfiguration.java:
import com.mongodb.client.MongoClients;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
@Configuration
public class MongoConfiguration {
public static final String MONGODB_URI = "mongodb://%s:%s@%s/%s?%s";
@Value("${spring.data.db1.username}")
private String user;
@Value("${spring.data.db1.password}")
private String password;
@Value("${spring.data.db1.hosts}")
private String hosts;
@Value("${spring.data.db1.database}")
private String database;
@Value("${spring.data.mongodb.options:authSource=admin&tls=true&maxPoolSize=10&minPoolSize=2&connectTimeoutMS=60000&socketTimeoutMS=60000}")
private String options;
@Value("${spring.data.db2.username}")
private String user2;
@Value("${spring.data.db2.password}")
private String password2;
@Value("${spring.data.db2.hosts}")
private String hosts2;
@Value("${spring.data.db2.database}")
private String db2;
@Value("${spring.data.db2.options:authSource=admin&tls=true&maxPoolSize=10&minPoolSize=2&connectTimeoutMS=60000&socketTimeoutMS=60000}")
private String options3;
@Value("${spring.data.db3.username}")
private String user3;
@Value("${spring.data.db3.password}")
private String password3;
@Value("${spring.data.db3.hosts}")
private String hosts3;
@Value("${spring.data.db3.database}")
private String db3;
@Value("${spring.data.db3.options:authSource=admin&tls=true&maxPoolSize=10&minPoolSize=2&connectTimeoutMS=60000&socketTimeoutMS=60000}")
private String options3;
@Primary
@Bean(name = PrimaryMongoConfig.MONGO_TEMPLATE)
public MongoTemplate primaryMongoTemplate() {
return new MongoTemplate(primaryFactory());
}
@Bean
@Qualifier(SecondaryMongoConfig.MONGO_TEMPLATE)
public MongoTemplate secondaryMongoTemplate() {
return new MongoTemplate(secondaryFactory());
}
@Bean
@Qualifier(ThirdConfig.MONGO_TEMPLATE)
public MongoTemplate thirdMongTempate() {
return new MongoTemplate(thirdFactory());
}
@Bean
public MongoDatabaseFactory thirdFactory() {
String uri = String.format(MONGODB_URI, user3, escape(password3), hosts3, database3, options3);
return new SimpleMongoClientDatabaseFactory(MongoClients.create(uri), database3);
}
@Bean
@Primary
public MongoDatabaseFactory primaryFactory() {
String uri = String.format(MONGODB_URI, user, escape(password), hosts, database, options);
return new SimpleMongoClientDatabaseFactory(MongoClients.create(uri), database);
}
@Bean
public MongoDatabaseFactory secondaryFactory() {
String uri = String.format(MONGODB_URI, user2, escape(password2), hosts2, database2, options2);
return new SimpleMongoClientDatabaseFactory(MongoClients.create(uri), database2);
}
private String escape(String password) {
return password.replace("@", "%40")
.replace("/", "%2F")
.replace("?", "%3F")
.replace("[", "%5B")
.replace("]", "%5D")
.replace(",", "%2C")
.replace("#", "%23");
}
}
新建 PrimaryMongoConfig.java:
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
@Configuration
@EnableMongoRepositories(basePackages = "com.abc.xyz.db1",
mongoTemplateRef = PrimaryMongoConfig.MONGO_TEMPLATE)
public class PrimaryMongoConfig {
protected static final String MONGO_TEMPLATE = "primaryMongoTemplate";
}
新建SecondaryMongoConfig.java:
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
@Configuration
@EnableMongoRepositories(basePackages = "com.abc.xyz.db2",
mongoTemplateRef = PrimaryMongoConfig.MONGO_TEMPLATE)
public class SecondaryMongoConfig {
protected static final String MONGO_TEMPLATE = "secondaryMongoTemplate";
}
新建 ThirdMongoConfig.java:
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
@Configuration
@EnableMongoRepositories(basePackages = "com.abc.xyz.db3",
mongoTemplateRef = PrimaryMongoConfig.MONGO_TEMPLATE)
public class ThirdMongoConfig {
protected static final String MONGO_TEMPLATE = "thirdMongoTemplate";
}
当然你也可以把上面第一个java文件分散到 Primary, Secondary, Third中去,这样只要三个文件,更清晰明了一些。
3. 创建包目录和Repository
在程序源码目录下,新建对应的 com.abc.xyz.db1, com.abc.xyz.db2, com.abc.xyz.db3 等三个包目录,然后把对应数据库的 Repository 的定义放到对应的目录下。
例如:
import com.abc.xyz.Order;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface OrderRepository extends MongoRepository<Order, String> {
}
4. 使用
使用时按正常的方式 @Autowired 即可,对于 Template这个公共对象,我们需要以修饰词限定即可。
例如:
@Autowired
private OrderRepository orderRepository;
@Autowired
@Qualifier(SecondaryMongoConfig.MONGO_TEMPLATE)
private MongoTemplate template2;