SpringBoot 整合mongoDB并自定义连接池,实现多数据源配置

news/2025/3/3 8:36:52/

       要想在同一个springboot项目中使用多个数据源,最主要是每个数据源都有自己的mongoTemplate和MongoDbFactory。mongoTemplate和MongoDbFactory是负责对数据源进行交互的并管理链接的。

       spring提供了一个注解@EnableMongoRepositories 用来注释在某些路径下的MongoRepositor实现类使用哪个MongoTemplate实例。当然如果我们是直接使用MongoTemplate操作,那么只需要使用于数据库对应的MongoTemplate即可。

代码结果如下:

首先实现两个config,实现对MongoTemplate和MongoDbFactory的配置

  • mongoTemplate1和mongoDbFactory1:并使用@EnableMongoRepositories指定在“com.zhong.springdemo.mangodbdome.mongodb1”目录下的MongoRepositor使用这些配置。
@Configuration
//指定com.zhong.springdemo.mangodbdome.mongodb1路径下的MongoRepository使用 容器中的  mongoTemplate1实例
@EnableMongoRepositories(mongoTemplateRef = "mongoTemplate1",basePackages = {"com.zhong.springdemo.mangodbdome.mongodb1"})
public class MongoDbConfigure {@AutowiredMongoDbFactoryProperties mongoDbFactoryProperties;/*** 自定义 mongoTemplate 实现多数据源配置*/@Bean("mongoTemplate1")public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory1, MongoMappingContext context){MappingMongoConverter mappingMongoConverter = mappingMongoConverter(mongoDbFactory1, context);MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory1, mappingMongoConverter);return mongoTemplate;}/*** 自定义mongo连接池* @param properties 私有配置* @return*/@Bean("mongoDbFactory1")public MongoDbFactory mongoDbFactory(MongoDbProperties properties) {//创建客户端参数MongoClientOptions options = mongoClientOptions(properties);//解析地址List<ServerAddress> serverAddresses = new ArrayList<>();for (String address : properties.getAddress().split(",")) {String[] hostAndPort = address.split(":");String host = hostAndPort[0];Integer port = Integer.parseInt(hostAndPort[1]);ServerAddress serverAddress = new ServerAddress(host, port);serverAddresses.add(serverAddress);}//创建认证客户端MongoCredential mongoCredential = MongoCredential.createScramSha1Credential(properties.getUsername(),properties.getAuthenticationDatabase() != null ? properties.getAuthenticationDatabase() : properties.getDatabase(),properties.getPassword().toCharArray());MongoClient mongoClient = new MongoClient(serverAddresses.get(0), mongoCredential, options);//集群模式if (serverAddresses.size() > 1) {mongoClient = new MongoClient(serverAddresses, mongoCredential, null);}/** 创建非认证客户端*///MongoClient mongoClient = new MongoClient(serverAddresses, mongoClientOptions);return new SimpleMongoDbFactory(mongoClient, properties.getDatabase());}/*** mongo客户端参数配置* @return*/private MongoClientOptions mongoClientOptions(MongoDbProperties properties) {MongoDbFactoryProperties factoryProperties = this.mongoDbFactoryProperties;return MongoClientOptions.builder().connectTimeout(factoryProperties.getConnectionTimeoutMs()).socketTimeout(factoryProperties.getReadTimeoutMs()).applicationName(factoryProperties.getApplicationName()).heartbeatConnectTimeout(factoryProperties.getHeartbeatConnectionTimeoutMs()).heartbeatSocketTimeout(factoryProperties.getHeartbeatReadTimeoutMs()).heartbeatFrequency(factoryProperties.getHeartbeatFrequencyMs()).minHeartbeatFrequency(factoryProperties.getMinHeartbeatFrequencyMs()).maxConnectionIdleTime(factoryProperties.getConnectionMaxIdleTimeMs()).maxConnectionLifeTime(factoryProperties.getConnectionMaxLifeTimeMs()).maxWaitTime(factoryProperties.getPoolMaxWaitTimeMs()).connectionsPerHost(factoryProperties.getConnectionsPerHost()).threadsAllowedToBlockForConnectionMultiplier(factoryProperties.getThreadsAllowedToBlockForConnectionMultiplier()).minConnectionsPerHost(factoryProperties.getMinConnectionsPerHost()).build();}/*** monogo 转换器* @return*/private MappingMongoConverter mappingMongoConverter(MongoDbFactory mongoDbFactory1, MongoMappingContext context) {DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory1);MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);//此处是去除插入数据库的 _class 字段mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));return mappingConverter;}
}
  • mongoTemplate2和mongoDbFactory2:并使用@EnableMongoRepositories指定在“com.zhong.springdemo.mangodbdome.mongodb2”目录下的MongoRepositor使用这些配置。
@Configuration
//指定com.zhong.springdemo.mangodbdome.mongodb2路径下的MongoRepository使用 容器中的  mongoTemplate2实例
@EnableMongoRepositories(mongoTemplateRef = "mongoTemplate2",basePackages = {"com.zhong.springdemo.mangodbdome.mongodb2"})
public class MongoDbConfigure2 {@AutowiredMongoDbFactoryProperties mongoDbFactoryProperties;/*** 自定义 mongoTemplate 实现多数据源配置*/@Bean("mongoTemplate2")public MongoTemplate mongoTemplate(MongoDbFactory mongoDbFactory2, MongoMappingContext context){MappingMongoConverter mappingMongoConverter = mappingMongoConverter(mongoDbFactory2, context);MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory2, mappingMongoConverter);return mongoTemplate;}/*** 自定义mongo连接池* @param properties 私有配置* @return*/@Bean("mongoDbFactory2")public MongoDbFactory mongoDbFactory2(MongoDbProperties2 properties) {//创建客户端参数MongoClientOptions options = mongoClientOptions(properties);//解析地址List<ServerAddress> serverAddresses = new ArrayList<>();for (String address : properties.getAddress().split(",")) {String[] hostAndPort = address.split(":");String host = hostAndPort[0];Integer port = Integer.parseInt(hostAndPort[1]);ServerAddress serverAddress = new ServerAddress(host, port);serverAddresses.add(serverAddress);}//创建认证客户端MongoCredential mongoCredential = MongoCredential.createScramSha1Credential(properties.getUsername(),properties.getAuthenticationDatabase() != null ? properties.getAuthenticationDatabase() : properties.getDatabase(),properties.getPassword().toCharArray());MongoClient mongoClient = new MongoClient(serverAddresses.get(0), mongoCredential, options);//集群模式if (serverAddresses.size() > 1) {mongoClient = new MongoClient(serverAddresses, mongoCredential, null);}/** 创建非认证客户端*///MongoClient mongoClient = new MongoClient(serverAddresses, mongoClientOptions);return new SimpleMongoDbFactory(mongoClient, properties.getDatabase());}/*** mongo客户端参数配置* @return*/private MongoClientOptions mongoClientOptions(MongoDbProperties2 properties) {MongoDbFactoryProperties factoryProperties = this.mongoDbFactoryProperties;return MongoClientOptions.builder().connectTimeout(factoryProperties.getConnectionTimeoutMs()).socketTimeout(factoryProperties.getReadTimeoutMs()).applicationName(factoryProperties.getApplicationName()).heartbeatConnectTimeout(factoryProperties.getHeartbeatConnectionTimeoutMs()).heartbeatSocketTimeout(factoryProperties.getHeartbeatReadTimeoutMs()).heartbeatFrequency(factoryProperties.getHeartbeatFrequencyMs()).minHeartbeatFrequency(factoryProperties.getMinHeartbeatFrequencyMs()).maxConnectionIdleTime(factoryProperties.getConnectionMaxIdleTimeMs()).maxConnectionLifeTime(factoryProperties.getConnectionMaxLifeTimeMs()).maxWaitTime(factoryProperties.getPoolMaxWaitTimeMs()).connectionsPerHost(factoryProperties.getConnectionsPerHost()).threadsAllowedToBlockForConnectionMultiplier(factoryProperties.getThreadsAllowedToBlockForConnectionMultiplier()).minConnectionsPerHost(factoryProperties.getMinConnectionsPerHost()).build();}/*** monogo 转换器* @return*/private MappingMongoConverter mappingMongoConverter(MongoDbFactory factory, MongoMappingContext context) {DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);//此处是去除插入数据库的 _class 字段mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));return mappingConverter;}
}
  • Repository实现

实现mongdb1下的repository---UserInfoTestRepository,UserInfoTestRepository使用的是mongoTemplate2和mongoDbFactory2

@Repository
public interface UserInfoTestRepository extends MongoRepository<UserInfoEntity, String> {List<UserInfoEntity> findByUserNameLike(String username);List<UserInfoEntity> findByUserName(String username);
}

实现mongdb2下的repository---UserInfRepository, UserInfRepository使用的是mongoTemplate1和mongoDbFactory1

@Repository
public interface UserInfoRepository extends MongoRepository<UserInfoEntity, String> {List<UserInfoEntity> findByUserNameLike(String username);List<UserInfoEntity> findByUserName(String username);
}
  •  实现service

使用Repository实现的访问的service

@Service
public class UserInfoServiceImpl implements UserInfoService {@Autowiredprivate UserInfoRepository userInfoRepository;@Autowiredprivate UserInfoTestRepository userInfoTestRepository;@Overridepublic List<UserInfoEntity> findByUserName(String userName){return userInfoRepository.findByUserName(userName);}@Overridepublic int saveTestUser(List<UserInfoDto> userInfoDtos) {List<UserInfoEntity> userInfoEntities = Lists.newArrayList();for(UserInfoDto userInfoDto : userInfoDtos){UserInfoEntity userInfoEntity = new UserInfoEntity();BeanUtils.copyProperties(userInfoDto, userInfoEntity);userInfoEntities.add(userInfoEntity);}userInfoTestRepository.saveAll(userInfoEntities);return userInfoEntities.size();}@Overridepublic int saveUser(List<UserInfoDto> userInfoDtos) {List<UserInfoEntity> userInfoEntities = Lists.newArrayList();for(UserInfoDto userInfoDto : userInfoDtos){UserInfoEntity userInfoEntity = new UserInfoEntity();BeanUtils.copyProperties(userInfoDto, userInfoEntity);userInfoEntities.add(userInfoEntity);}userInfoRepository.saveAll(userInfoEntities);return userInfoEntities.size();}
}

使用MongoTemplate实现的访问的service

@Service
public class UserInfoMongoTemplateServiceImpl implements UserInfoMongoTemplateService {@AutowiredMongoTemplate mongoTemplate1;@AutowiredMongoTemplate mongoTemplate2;@Overridepublic List<UserInfoEntity> findByUserName(String userName){Criteria criteria = Criteria.where("user_name").is(userName);return mongoTemplate1.find(getQueryFilter(criteria), UserInfoEntity.class);}@Overridepublic int saveTestUser(List<UserInfoDto> userInfoDtos) {List<UserInfoEntity> userInfoEntities = Lists.newArrayList();for(UserInfoDto userInfoDto : userInfoDtos){UserInfoEntity userInfoEntity = new UserInfoEntity();BeanUtils.copyProperties(userInfoDto, userInfoEntity);userInfoEntities.add(userInfoEntity);}mongoTemplate1.insert(userInfoEntities, UserInfoEntity.class);return userInfoEntities.size();}@Overridepublic int saveUser(List<UserInfoDto> userInfoDtos) {List<UserInfoEntity> userInfoEntities = Lists.newArrayList();for(UserInfoDto userInfoDto : userInfoDtos){UserInfoEntity userInfoEntity = new UserInfoEntity();BeanUtils.copyProperties(userInfoDto, userInfoEntity);userInfoEntities.add(userInfoEntity);}mongoTemplate2.insert(userInfoEntities, UserInfoEntity.class);return userInfoEntities.size();}private Query getQueryFilter(Criteria criteria, String  ...parms) {criteria = criteria == null ? new Criteria() : criteria;Query query = new Query();query.addCriteria(criteria);if(parms != null && parms.length > 0){Field fields = query.fields();for(String parm : parms){fields.include(parm);}}return query;}
}

 两个数据源信息配置properties.yaml:

zhong:#自定义的mongodb测试data:mongodb:database: zhong-mongopassword: 123456address: 127.0.0.1:27017username: adminauthenticationDatabase: adminmongodb2:database: test-mongopassword: 123456address: 127.0.0.1:27017username: adminauthenticationDatabase: admin

测试类:

@Component
public class MongoStartTest implements CommandLineRunner {@AutowiredUserInfoService userInfoService;@AutowiredUserInfoMongoTemplateService userInfoMongoTemplateService;@Overridepublic void run(String... args) throws Exception {for(int i = 0; i < 25; i++){UserInfoDto userInfoDto = new UserInfoDto();userInfoDto.setUserId(UUID.randomUUID().toString().replace("-", ""));userInfoDto.setUserName("用户名" + i);userInfoDto.setAuthor("登录名" + i);userInfoDto.setPwd("123456" + i);userInfoDto.setCreateTime(new Date());userInfoService.saveTestUser(Lists.newArrayList(userInfoDto));userInfoService.saveUser(Lists.newArrayList(userInfoDto));}for(int i = 100; i < 125; i++){UserInfoDto userInfoDto = new UserInfoDto();userInfoDto.setUserId(UUID.randomUUID().toString().replace("-", ""));userInfoDto.setUserName("用户名" + i);userInfoDto.setAuthor("登录名" + i);userInfoDto.setPwd("123456" + i);userInfoDto.setCreateTime(new Date());userInfoMongoTemplateService.saveTestUser(Lists.newArrayList(userInfoDto));userInfoMongoTemplateService.saveUser(Lists.newArrayList(userInfoDto));}userInfoService.findByUserName("用户名");userInfoMongoTemplateService.findByUserName("用户名");}
}

结果如图:

数据的确被插入到不同的库中了

参考:

http://www.voidcn.com/article/p-zqjtjvhm-bvu.html


http://www.ppmy.cn/news/1576247.html

相关文章

游戏引擎学习第128天

开始 然而&#xff0c;我们仍然有一些工作要做&#xff0c;渲染部分并没有完全完成。虽然现在已经能够运行游戏&#xff0c;而且帧率已经可以接受&#xff0c;但仍然有一些东西需要进一步完善。正在使用调试构建编译版本&#xff0c;虽然调试版本的性能不如优化版本&#xff0…

从零开始开发纯血鸿蒙应用之语音朗读

从零开始开发纯血鸿蒙应用 〇、前言一、API 选型1、基本情况2、认识TextToSpeechEngine 二、功能集成实践1、改造右上角菜单2、实现语音播报功能2.1、语音引擎的获取和关闭2.2、设置待播报文本2.3、speak 目标文本2.4、设置语音回调 三、总结 〇、前言 中华汉字洋洋洒洒何其多…

final 关键字在不同上下文中的用法及其名称

1. final 变量 名称&#xff1a;final 变量&#xff08;常量&#xff09;。 作用&#xff1a;一旦赋值后&#xff0c;值不能被修改。 分类&#xff1a; final 实例变量&#xff1a;必须在声明时或构造函数中初始化。 final 静态变量&#xff1a;必须在声明时或静态代码块中初…

Hive-05之查询 分组、排序、case when、 什么情况下Hive可以避免进行MapReduce

一、目标 掌握hive中select查询语句中的基本语法掌握hive中select查询语句的分组掌握hive中select查询语句中的join掌握hive中select查询语句中的排序 二、要点 1. 基本查询 注意 SQL 语言大小写不敏感SQL 可以写在一行或者多行关键字不能被缩写也不能分行各子句一般要分行…

【再谈设计模式】备忘录模式~对象状态的守护者

一、引言 在软件开发过程中&#xff0c;我们常常会遇到需要保存对象状态以便在之后恢复的情况。例如&#xff0c;在文本编辑器中&#xff0c;我们可能想要撤销之前的操作&#xff1b;在游戏中&#xff0c;玩家可能希望恢复到之前的某个游戏状态。备忘录模式&#xff08;Memento…

NIM平台开发基于提示工程的大语言模型(LLM)应用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1 课程介绍1.1 Goals1.2 content 2 提示词简介2.1 NVIDIA NIMs 用于提示工程2.2 OpenAI API 交互2.3 与 LangChain 交互实现聊天2.4 流式处理和批处理2.5 迭代式提示…

《白帽子讲 Web 安全:点击劫持》

目录 摘要&#xff1a; 一、点击劫持概述 二、点击劫持的实现示例&#xff1a;诱导用户收藏指定淘宝商品 案例 构建恶意页面&#xff1a; 设置绝对定位和z - index&#xff1a; 控制透明度&#xff1a; 三、其他相关攻击技术 3.1图片覆盖攻击与 XSIO 3.2拖拽劫持与数据…

大白话实战docker

为什么有docker 假设有这么一个场景,作为新时代的全栈工程师,某一天你接手一个项目,搭建好项目以后,还需要一台服务器,在它上面安装mysql、redis等项目中常用的中间件,于是你网上搜索Linux如何安装mysql、redis,照着网上的资料进行复制粘贴,结果发现老是运行不成功,好…