我想要的效果是,一个类统一管理多数据源,我传个参数进去,它就能返回我对应的mongotemplate
但是根据"mongbodb 多数据源"的关键词,找不到我想要的效果。
网上大多都是明确知道自己是几个数据源,然后每个数据源具体配置,然后业务代码调用的时候,直接注入不同的数据源,这样的话,不太利于以后的数据库扩容。
目录
网上找到的多数据源写法
自用易扩展的多数据源写法
比如如下的这种,我在网上找到的写法。
配的时候是这样的
spring:
data:
mongodb:
primary:
uri: mongodb://localhost:27017/primary
secondary:
uri: mongodb://localhost:27017/secondary
写配置class
@Configuration
public class PrimaryMongoConfig {
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.data.mongodb.primary")
public MongoClient primaryMongoClient() {
return MongoClients.create();
}
@Primary
@Bean(name = "primaryMongoTemplate")
public MongoTemplate primaryMongoTemplate() {
return new MongoTemplate(primaryMongoClient(), "primary");
}
}
@Configuration
public class SecondaryMongoConfig {
@Bean
@ConfigurationProperties(prefix = "spring.data.mongodb.secondary")
public MongoClient secondaryMongoClient() {
return MongoClients.create();
}
@Bean(name = "secondaryMongoTemplate")
public MongoTemplate secondaryMongoTemplate() {
return new MongoTemplate(secondaryMongoClient(), "secondary");
}
}
这样注入了2个Bean
@Service
public class ProductService {
@Autowired
@Qualifier("secondaryMongoTemplate")
private MongoTemplate mongoTemplate;
public void saveProduct(Product product) {
mongoTemplate.save(product);
}
}
通过标明名称的方式,来注入具体的数据源。
这种有个坏处,就是以后如果想扩展数据库,就必须来个类似于thirdMongoTemplate的玩意,然后需要写个switchCase的东西,返回具体的mongoTemplate
所以,我需要自己写个符合我需求的mongoTemplate的聚集类。
我的设计是,多数据源以配置文件里,数组的方式进行传入
如下
spring.data.mongodb.sources[0].url=mongodb://localhost:27017
spring.data.mongodb.sources[0].name=mongodb_0
spring.data.mongodb.sources[0].dbName=myTest
spring.data.mongodb.sources[1].url=mongodb://localhost:27017
spring.data.mongodb.sources[1].name=mongodb_1
spring.data.mongodb.sources[1].dbName=myTest_1
我现在暂时设置了2个数据源,url为真实链接,dbName为数据库名称,name为我之后要获取这玩意,设置的key名称。不用拘泥于这些名字,都是我自定义出来的。
对应这些配置,我定义了一个配置类去接。
@Data
@Component
@ConfigurationProperties(prefix = "spring.data.mongodb")
public class MongoConfig {
//sources跟配置文件的键名对应上,如果配置文件不叫这个,也跟着换下
private List sources;
}
因为配的是数组对象,也设置下该对象
@Data
public class MongoSource {
private String name;
private String url;
private String dbName;
}
@Data 是lombada插件的
然后构造一下我想要的,管理多数据源的类
public class MongoFactory {
// 这里的修饰符自己定吧,按你自己的需求
private Map dbMap = new HashMap<>();
public MongoFactory() {}
public void init(MongoConfig config) {
// 初始化多数据源的map吧
for (MongoSource item : config.getSources()) {
MongoClient client = MongoClients.create(item.getUrl());
dbMap.put(item.getName(), new MongoTemplate(client, item.getDbName()));
}
}
public MongoTemplate getTemplate(String dbName) {
return dbMap.get(dbName);
}
}
这里有个很坑的地方,new MongoTemplate(client, item.getDbName()),这里的第2个参数,是指链接里要填的dataBase名称,别乱填了
将这个类进行注册
@Configuration
public class BeanFactoryConfig {
//引入配置
@Resource private MongoConfig config;
//注册一下我自己造的factory
@Bean
public MongoFactory mongoFactory() {
MongoFactory factory = new MongoFactory();
factory.init(config);
return factory;
}
}
进行使用,直接进行注入
@Resource private MongoFactory factory;
比如说,判断该数据源是否存在某集合
boolean flag =factory.getTemplate(name).collectionExists(collectionName);
factory.getTemplate(name) 根据name,可以从map拿到对应的数据源。
以上,我的需求就实现完毕。