当前位置: 首页 > news >正文

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

       要想在同一个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 {

    @Autowired
    MongoDbFactoryProperties 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 {

    @Autowired
    MongoDbFactoryProperties 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 {
    @Autowired
    private UserInfoRepository userInfoRepository;

    @Autowired
    private UserInfoTestRepository userInfoTestRepository;

    @Override
    public List<UserInfoEntity> findByUserName(String userName){
        return userInfoRepository.findByUserName(userName);
    }

    @Override
    public 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();
    }

    @Override
    public 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 {
    @Autowired
    MongoTemplate mongoTemplate1;

    @Autowired
    MongoTemplate mongoTemplate2;

    @Override
    public List<UserInfoEntity> findByUserName(String userName){
        Criteria criteria = Criteria.where("user_name").is(userName);
        return mongoTemplate1.find(getQueryFilter(criteria), UserInfoEntity.class);
    }

    @Override
    public 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();
    }

    @Override
    public 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-mongo
      password: 123456
      address: 127.0.0.1:27017
      username: admin
      authenticationDatabase: admin
    mongodb2:
      database: test-mongo
      password: 123456
      address: 127.0.0.1:27017
      username: admin
      authenticationDatabase: admin

测试类:

@Component
public class MongoStartTest implements CommandLineRunner {

    @Autowired
    UserInfoService userInfoService;

    @Autowired
    UserInfoMongoTemplateService userInfoMongoTemplateService;

    @Override
    public 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

相关文章:

  • 【软考】【2025年系统分析师拿证之路】【啃书】第十四章 软件实现与测试(十五)
  • 进阶面试题 ——‘说说你对浏览器的V8引擎的理解’
  • python开发之 __init__.py的一些基本用法
  • C高级(shell)
  • C高级----shell作业
  • 山东大学软件学院nosql实验二
  • pta天梯L1-004 计算摄氏温度
  • 基于 Spring AI 的 HIS 系统智能化改造
  • (七)消息队列-Kafka 序列化avro(传递)
  • 深入理解 Kubernetes 命名空间:高效管理与隔离资源的关键
  • React Native 原理
  • TDengine 中的数据库
  • C++-第十三章:红黑树
  • webpack5在生产环境屏蔽掉控制台打印 失效处理
  • Nginx 配置前端后端服务
  • 矩阵 trick 系列 题解
  • 【51单片机】快速入门
  • 关于mysql 表中字段存储JSON对象对JSON对象中的bolean字段进行查询的方式
  • 【原创】Ubuntu 24搭建Ollama+ DeepSeek局域网服务器
  • salesforce 为什么无法关闭task,显示:insufficient access rights on object id
  • 董军在第六届联合国维和部长级会议上作大会发言
  • 北京警方:海淀发生小客车刮碰行人事故4人受伤,肇事司机已被查获
  • 南方降水频繁暴雨连连,北方高温再起或现40°C酷热天气
  • 爱德华多·阿拉纳宣誓就任秘鲁新总理
  • 京东回应外卖系统崩溃:订单暴涨所致,已恢复
  • 国务院办公厅印发《国务院2025年度立法工作计划》