# dynamic-mongo-spring-boot-starter
**Repository Path**: anonuser/dynamic-mongo-spring-boot-starter
## Basic Information
- **Project Name**: dynamic-mongo-spring-boot-starter
- **Description**: mongo多数据源
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2025-02-07
- **Last Updated**: 2025-02-07
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
#### 1,增加dynamic-mongo-spring-boot-starter的pom引用
```xml
com.wuuxiang
dynamic-mongo-spring-boot-starter
0.0.1
```
#### 2,yml文件里面增加mongo多数据源的配置
```yaml
spring:
data:
mongodb:
dynamic:
primary: i5x
remove-under-class: true
datasource:
i5x:
uri: mongodb://username:password@ip:port/i5xdatabase?replicaSet=repl&authSource=i5xauthdatabase&readPreference=secondaryPreferred
fans:
uri: mongodb://username:password@ip:port/fansdatabase?replicaSet=repl&authSource=fansauthdatabase&readPreference=secondaryPreferred
```
#### 3,代码的类上,或者方法上面使用@MongoDS("xxx")来指定数据源,不指定的话,默认走primary数据源
```java
//类上面
@MongoDS("i5x")
@Service
public class WaiMaiShopServiceImpl extends BaseServiceImpl implements WaiMaiShopService {
// 每组最大数量
private static final Integer MAX_GROUP_SIZE = 200;
@Autowired
private LbsQqUtil lbsQqUtil;
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private DeliveryMobileSchemeRepository deliveryMobileSchemeRepository;
}
```
```
//方法上面
@MongoDS("fans")
@Override
public PhoDeliveryInstall getPhoDeliveryInstallByMcId(Object zoneShardingKey,Integer gcId,Integer mcId,Integer deliveryInstallType){
List phoDeliveryInstalls=getPhoDeliveryInstall(zoneShardingKey,gcId,Lists.newArrayList(mcId),deliveryInstallType);
if(CollectionUtils.isEmpty(phoDeliveryInstalls)){
return null;
}
return phoDeliveryInstalls.get(0);
}
```
#### 4,约定
- 本框架只做 切换数据源 这件核心的事情,并不限制你的具体操作,切换了数据源可以做任何CRUD。
- 方法上的注解优先于类上注解。
- MongoDS支持继承抽象类上的MongoDS,暂不支持继承接口上的MongoDS。
#### 5,原理
spring内有两种操作mongo的方式
1,MongoTemplate
2,MongoRepository
MongoTemplate的方式:
在MongoDatabaseFactoryDependentConfiguration中可以看到,MongoTemplate内部注入了一个MongoDatabaseFactory
```
@Bean
@ConditionalOnMissingBean(MongoOperations.class)
MongoTemplate mongoTemplate(MongoDatabaseFactory factory, MongoConverter converter) {
return new MongoTemplate(factory, converter);
}
```
在MongoDatabaseFactoryConfiguration中可以看到,MongoDatabaseFactory为SimpleMongoClientDatabaseFactory实例
```
@Bean
MongoDatabaseFactorySupport> mongoDatabaseFactory(MongoClient mongoClient, MongoProperties properties) {
return new SimpleMongoClientDatabaseFactory(mongoClient, properties.getMongoClientDatabase());
}
```
然后后续的MongoDatabase连接都是由SimpleMongoClientDatabaseFactory来维护。
所以我们的思路很简单,自定义一个DynamicMongoDatabaseFactory,内部维护一个Map来切换多数据源。
Main-->MongoTemplate-->DynamicMongoDatabaseFactory-->根据@MongoDS注解的value从Map中取出对应SimpleMongoClientDatabaseFactory-->操作CRUD Mongo库
MongoRepository的方式:
MongoRepository的实现类为SimpleMongoRepository,可以看到其内部注入了MongoOperations
```
public SimpleMongoRepository(MongoEntityInformation metadata, MongoOperations mongoOperations) {
Assert.notNull(metadata, "MongoEntityInformation must not be null!");
Assert.notNull(mongoOperations, "MongoOperations must not be null!");
this.entityInformation = metadata;
this.mongoOperations = mongoOperations;
}
```
而MongoTemplate正是MongoOperations的实现类,所以其实MongoRepository也是通过MongoTemplate来操作Mongo库的。