springboot 多个数据库配置

本文介绍如何在Spring Boot项目中配置主从两个MongoDB数据源,并提供详细的pom依赖、yaml配置、代码实现步骤及遇到的问题解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、pom文件依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

二、yaml文件配置

spring:
  data:
    mongodb:
      primary:
        uri: mongodb://root:service_ip@10.10.10.10:27017/database1_name?authSource=admin&slaveOk=true&replicaSet=rs1&write=1&readPreference=secondaryPreferred&connectTimeoutMS=300000
      secondary:
        uri: mongodb://root:service_ip@10.10.10.10:27017/database2_name/?authSource=admin&slaveOk=true&replicaSet=rs1&write=1&readPreference=secondaryPreferred&connectTimeoutMS=300000

primary:主数据源
secondary:副数据源

三、代码实现

1、main函数配置
// 排除springBoot启动自动加载MongoDB
@SpringBootApplication(exclude= {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})

public class ContentServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(ContentServiceApplication.class, args);
    }

}

在启动类上添加注解exclude,排除springBoot启动时自动加载MongoDB;

2、创建mongodb工厂
package com.content.admin.contentservice.config;

import com.mongodb.ConnectionString;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDbFactory;

public abstract class AbstractMongoConfig {
    
    private String uri; // mongodb 地址

    /**
     * 获取MongoTemplate
     * @return
     * @throws Exception
     */
    public abstract MongoTemplate getMongoTemplate() throws Exception;

    /**
     * 创建mongodb工厂
     * @return
     * @throws Exception
     */
    public MongoDatabaseFactory mongoDbFactory() throws Exception
    {
        ConnectionString connectionString = new ConnectionString(uri);
        return new SimpleMongoClientDbFactory(connectionString);

//        // 参考其他博客,但我本地MongoClientURI始终找不到。改写成上面的写法
//        MongoClientURI mongoClientURI = new MongoClientURI(uri);
//        return new SimpleMongoDbFactory(mongoClientURI);
    }

    public String getUri() {
        return uri;
    }

    public void setUri(String uri) {
        this.uri = uri;
    }
}

private String uri;uri的命名要和yaml文件中的命名保持一致。

3、主数据源配置
package com.content.admin.contentservice.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.mongodb.core.MongoTemplate;

@Configuration
@ConfigurationProperties(prefix = "spring.data.mongodb.primary")
public class PrimaryMongoConfig extends AbstractMongoConfig {

    @Primary //在使用@Autowired注入的时候,如果不特殊指明(特殊指明请用@Qualifier的讲解),那么默认就注入被@Primary标记的类
    @Override
    @Bean(name = "mongoTemplate")
//    @Bean(name = "primaryMongoTemplate")
    public MongoTemplate getMongoTemplate() throws Exception {
        return new MongoTemplate(mongoDbFactory());
    }
}

这里要注意,@ConfigurationProperties(prefix = "spring.data.mongodb.primary") 中的路径要和yaml配置文件的对应。

4、副数据源配置
package com.content.admin.contentservice.config;


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;

@Configuration
@ConfigurationProperties(prefix = "spring.data.mongodb.secondary") 
public class SecondaryMongoConfig extends AbstractMongoConfig {

    @Override
    @Bean(name = "secondaryMongoTemplate")
    public MongoTemplate getMongoTemplate() throws Exception {
        return new MongoTemplate(mongoDbFactory());
    }
}

这里要注意,@ConfigurationProperties(prefix = "spring.data.mongodb.secondary") 中的路径要和yaml配置文件的对应。

5、工具封装
package com.content.admin.contentservice.util;

import com.mongodb.MongoException;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

@Component
public class MongoUtils {
//    @Resource
//    MongoTemplate mongoTemplate;

	// 主数据源
    @Autowired
    @Qualifier(value = "mongoTemplate")
//    @Qualifier(value = "primaryMongoTemplate")
    private MongoTemplate mongoTemplate;

	// 副数据源
    @Autowired
    @Qualifier(value = "secondaryMongoTemplate")
    private MongoTemplate mongoTemplate2;


    public String getCurrentCollection(Class<?> o){
        return mongoTemplate.getCollectionName(o);
    }
    public void createCollection(String collection){
        if(!mongoTemplate.collectionExists(collection)){
            mongoTemplate.createCollection(collection);
        }
    }

    public Object add(Object o , String collectionName){
        Object result;
        try{
            result = mongoTemplate.insert(o , collectionName);
        }catch (MongoException e){
            System.out.println(e.getMessage());
            throw new MongoException(e.getMessage());
        }
        return result;
    }

    public void delete(Query query , Object obj , String collectionName){
        mongoTemplate.remove(query, obj .getClass(), collectionName);
    }

    public boolean update(Query query , Update update , Class<?> clazz , String collectionName){
        UpdateResult result =  mongoTemplate.updateMulti(query, update, clazz, collectionName);
        return result.wasAcknowledged();
    }

    public List<?> getAllByCollectionName(Class<?> clazz , String collectionName){
        return mongoTemplate.findAll(clazz,collectionName);
    }

    public List <?> getByConditionAndCollectionName(Query query , Class<?> clazz , String collectionName){
        return mongoTemplate.find(query, clazz, collectionName);
    }

    public Object getOneByCondition(Query query , Class<?> clazz , String collectionName){
        return mongoTemplate.findOne(query, clazz , collectionName);
    }

    public Boolean exists(Query query , Class<?> clazz , String collectionName){
        return mongoTemplate.exists(query , clazz ,collectionName);
    }

    public DeleteResult remove(Query query , Class<?> clazz , String collectionName){
        return mongoTemplate.remove(query , clazz , collectionName);
    }
    public long getCount(Query query, Class<?> clazz , String collection){
        return mongoTemplate.count(query, clazz , collection);
    }

    public List <?> lookUp(Aggregation aggregation , String table , Class<?> clazz){
        return mongoTemplate.aggregate(aggregation , table , clazz).getMappedResults();
    }

    public Object add2(Object o , String collectionName){
        Object result;
        try{
            result = mongoTemplate2.insert(o , collectionName);
        }catch (MongoException e){
            System.out.println(e.getMessage());
            throw new MongoException(e.getMessage());
        }
        return result;
    }

    public Object getOneByCondition2(Query query , Class<?> clazz , String collectionName){
        return mongoTemplate2.findOne(query, clazz , collectionName);
    }

    public Boolean exists2(Query query , Class<?> clazz , String collectionName){
        return mongoTemplate2.exists(query , clazz ,collectionName);
    }
}

6、使用
package com.content.admin.contentservice.service;

import com.content.admin.contentservice.util.MongoUtils;
import javax.annotation.Resource;

@Service
public class TopicServiceImpl implements TopicService {

    @Resource
    MongoUtils mongoUtils;

    @Override
    public ResponseBean getList(TopicVo topicVo){
    	
    	...
    	
        List<?> list =  mongoUtils.getOneByCondition(query , TopicEntity.class , collection);
		
		...
    }
}

TopicEntity.class是和数据库字段对应的entity。
collection是表名。

四、踩的坑

1、MongoClientURI找不到
public abstract class AbstractMongoConfig {

    private String uri; // mongodb 地址

    /**
     * 获取MongoTemplate
     * @return
     * @throws Exception
     */
    public abstract MongoTemplate getMongoTemplate() throws Exception;

    /**
     * 创建mongodb工厂
     * @return
     * @throws Exception
     */
    public MongoDatabaseFactory mongoDbFactory() throws Exception
    {
        ConnectionString connectionString = new ConnectionString(uri);
        return new SimpleMongoClientDbFactory(connectionString);

//        // 参考其他博客,但我本地MongoClientURI始终找不到。改写成上面的写法
//        MongoClientURI mongoClientURI = new MongoClientURI(uri);
//        return new SimpleMongoDbFactory(mongoClientURI);
    }

    public String getUri() {
        return uri;
    }

    public void setUri(String uri) {
        this.uri = uri;
    }
}

我本地在创建mongodb工厂时,始终找不到MongoClientURI,最后改成上面的写法。

2、找不到mongoTemplate

报错信息

com.content.admin.contentservice.shiro.ShiroConfig required a bean named 'mongoTemplate' that could not be found.

原因:找不到mongoTemplate

解决方法:
在配置主数据源时,把primaryMongoTemplate修改为mongoTemplate

参考链接:

https://blog.csdn.net/zhan107876/article/details/94588388
https://blog.csdn.net/jin809391761/article/details/89455587
https://zhangdhing.blog.csdn.net/article/details/88634598?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值