我想要的效果是,一個類統一管理多數據源,我傳個參數進去,它就能返回我對應的mongotemplate
但是根據"mongbodb 多數據源"的關鍵詞,找不到我想要的效果。
網上大多都是明確知道自己是幾個數據源,然后每個數據源具體配置,然后業務代碼調用的時候,直接注入不同的數據源,這樣的話,不太利于以后的數據庫擴容。
目錄
網上找到的多數據源寫法
自用易擴展的多數據源寫法
比如如下的這種,我在網上找到的寫法。
網上找到的多數據源寫法
配的時候是這樣的
spring:data:mongodb:primary:uri: mongodb://localhost:27017/primarysecondary: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<MongoSource> sources;
}
因為配的是數組對象,也設置下該對象
@Data
public class MongoSource {private String name;private String url;private String dbName;
}
@Data 是lombada插件的
然后構造一下我想要的,管理多數據源的類
public class MongoFactory {// 這里的修飾符自己定吧,按你自己的需求private Map<String, MongoTemplate> 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@Beanpublic 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拿到對應的數據源。
以上,我的需求就實現完畢。