大家好!
最近一直在研究如何在springboot中如何配置多个mongodb数据源,查阅了很多网上的资料发现,很多示例都是很久以前示例了,在新版本的spring-data-mongodb-3.0.2 中已经不再支持网络上的大部分的示例了,如:基于 SimpleMongoDbFactory 的这种方已经被废弃删除了,应改用SimpleMongoClientDatabaseFactory 方式,经过一天的研究终于总结出了最新的配置方式供大家参考:
步骤如下:
导入依赖:
<!-- spring-boot 版本 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/>
</parent>
<!-- spring-boot data mongodb 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
1.在yaml 文件中 配置两个以上mongo 集群数据源
spring:
data:
mongodb:
mpc:
uri: mongodb://用户名:密码@ip:port,ip:port/database
saas:
uri: mongodb://用户名:密码@ip:port,ip:port/database
2.排除springboot默认的mongo初始化机制
@SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
public class MpcExampleApplication {
public static void main(String[] args) {
SpringApplication.run(MpcExampleApplication.class, args);
}
}
3.生成多个MongoTemplate 并开启Repositor 操作并指定作用于哪个package
创建mongoSaasTemplate作用于"com.sun.mpc.example.storage.mongorpst.mpc" 下的Repository
/**
* 初始化mcp mongoMpcTemplate
* 如果不是多mongo数据源无需引入该配置
* 注:开启多数据源配置需要排除springboot默认的mongo初始化机制
* @SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
* @author liangjian
* @date
*/
@Slf4j
@Configuration
@EnableMongoRepositories(basePackages = "com.sun.mpc.example.storage.mongorpst.mpc", mongoTemplateRef = "mongoMpcTemplate")
public class MongoMpcTemplateConfig {
@Value("${spring.data.mongodb.mpc.uri}")
private String uri;
@Primary
@Bean(name = "mongoMpcTemplate")
public MongoTemplate mongoMpcTemplate() throws Exception {
log.info("-----------------------init mongoMpcTemplate success-----------------------------------");
return new MongoTemplate(mongoMpcFactory());
}
@Bean
@Primary
public MongoDatabaseFactory mongoMpcFactory() throws Exception {
SimpleMongoClientDatabaseFactory simpleMongoClientDbFactory = new SimpleMongoClientDatabaseFactory(uri);
return simpleMongoClientDbFactory;
}
}
创建mongoSaasTemplate作用于"com.sun.mpc.example.storage.mongorpst.saas" 下的Repository
/**
* 初始化saas mongoSaasTemplate
* 如果不是多mongo数据源无需引入该配置
* 注:开启多数据源配置需要排除springboot默认的mongo初始化机制
* @SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
* @author liangjian
* @date
*/
@Slf4j
@Configuration
@EnableMongoRepositories(basePackages = "com.sun.mpc.example.storage.mongorpst.saas", mongoTemplateRef = "mongoSaasTemplate")
public class MongoSaasTemplateConfig {
@Value("${spring.data.mongodb.saas.uri}")
private String uri;
@Primary
@Bean(name = "mongoSaasTemplate")
public MongoTemplate mongoSaasTemplate() throws Exception {
log.info("-----------------------init mongoSaasTemplate success-----------------------------------");
return new MongoTemplate(mongoSaasFactory());
}
@Bean
@Primary
public MongoDatabaseFactory mongoSaasFactory() throws Exception {
SimpleMongoClientDatabaseFactory simpleMongoClientDbFactory = new SimpleMongoClientDatabaseFactory(uri);
return simpleMongoClientDbFactory;
}
}
4.包结构截图
5.测试类
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(properties={"spring.profiles.active=int"})
public class MongoRepositoryMultiSourceTest {
@Autowired
private MStudentTestEntityRepository mstudentTestEntityRepository;
@Autowired
private SStudentTestEntityRepository sstudentTestEntityRepository;
@Test
public void contextLoads() {
mstudentTestEntityRepository.insert(MStudentTestEntity.builder()
.name("woshi m")
.age(20)
.sex(true)
.build());
sstudentTestEntityRepository.insert(SStudentTestEntity.builder()
.name("woshi s")
.age(20)
.sex(true)
.build());
}
}
最后虽然不是很详细,也没有具体说明,但是我想凡是对这块稍微有点了解跟研究的,一定能看懂,至此简单集成已经完成并且满足基本需求。
6.扩展 (选读)设置 auto_index_creation = true 自动创建索引失效问题
由于我们覆盖了 spring boot 自动装配mongo配置,导致 实体类的字段注解 @Indexed 自动创建索引失效,即下面的yml 配置不起作用。
spring:
data:
mongodb:
auto-index-creation: true #自动创建索引
为了解决这个问题我对配置类做了优化如下:
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.domain.EntityScanner;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.annotation.Persistent;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import java.util.Collections;
/**
* 初始化saas mongoSaasTemplate
* 如果不是多mongo数据源无需引入该配置
* 注:开启多数据源配置需要排除springboot默认的mongo初始化机制
* @SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
* @author liangjian
* @date
*/
@Slf4j
@Configuration
@EnableMongoRepositories(basePackages = "com.sun.mpc.example.storage.mongorpst.saas", mongoTemplateRef = "mongoSaasTemplate")
public class MongoSaasTemplateConfig {
@Value("${spring.data.mongodb.saas.uri}")
private String uri;
@Bean
public MongoTemplate mongoSaasTemplate(MongoDatabaseFactory mongoSaasFactory, MappingMongoConverter mongoSaasConverter) throws Exception {
log.info("-----------------------init mongoSaasTemplate success-----------------------------------");
return new MongoTemplate(mongoSaasFactory,mongoSaasConverter);
}
@Bean
public MongoDatabaseFactory mongoSaasFactory() throws Exception {
SimpleMongoClientDatabaseFactory simpleMongoClientDbFactory = new SimpleMongoClientDatabaseFactory(uri);
return simpleMongoClientDbFactory;
}
/**
* 设置AutoIndexCreation 等于 true 自动创建索引
* @param mongoSaasFactory
* @return org.springframework.data.mongodb.core.convert.MappingMongoConverter
* @author liangjian
*/
@Bean
MappingMongoConverter mongoSaasConverter(MongoDatabaseFactory mongoSaasFactory, ApplicationContext applicationContext) throws Exception {
MongoCustomConversions conversions = new MongoCustomConversions(Collections.emptyList());
DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoSaasFactory);
PropertyMapper mapper = PropertyMapper.get().alwaysApplyingWhenNonNull();
MongoMappingContext context = new MongoMappingContext();
mapper.from(true).to(context::setAutoIndexCreation);
context.setInitialEntitySet(new EntityScanner(applicationContext).scan(Document.class, Persistent.class));
context.setSimpleTypeHolder(conversions.getSimpleTypeHolder());
MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
mappingConverter.setCustomConversions(conversions);
return mappingConverter;
}
}
注意这段代码:
mapper.from(true).to(context::setAutoIndexCreation); 我写死为true 相当于无需yml配置即可实现自动创建索引,读者可根据实际情况,选择从yaml 中读取 auto-index-creation: true 配置,实现动态配置
完结~~~