# 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库的。