MongoDB多数据源配置与切换

在MongoDB中配置和使用多数据源主要涉及以下几个步骤:

  1. 定义多个数据源的配置

    • 在应用程序的配置文件中,定义多个MongoDB的数据源,例如在Spring Boot中可以通过application.yml或application.properties文件进行配置。
  2. 创建多个MongoTemplate Bean

    • 使用Spring框架的Java配置类,创建多个MongoTemplate Bean,每个Bean对应一个数据源。
  3. 使用动态切换数据源的方式

    • 使用Spring的AOP(Aspect-Oriented Programming)或其他方法,在运行时根据需要动态切换数据源。

以下是一个Spring Boot应用中配置和切换多数据源的示例:

1. 配置文件 (application.yml)

yaml 复制代码
spring:
  data:
    mongodb:
      primary:
        uri: mongodb://localhost:27017/primarydb
      secondary:
        uri: mongodb://localhost:27017/secondarydb

2. Java配置类

java 复制代码
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
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
public class MongoConfig {

    @Primary
    @Bean(name = "primaryMongoTemplate")
    public MongoTemplate primaryMongoTemplate() {
        MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017/primarydb");
        return new MongoTemplate(mongoClient, "primarydb");
    }

    @Bean(name = "secondaryMongoTemplate")
    public MongoTemplate secondaryMongoTemplate() {
        MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017/secondarydb");
        return new MongoTemplate(mongoClient, "secondarydb");
    }
}

3. 动态切换数据源

方法一:使用AOP动态切换数据源

你可以定义一个自定义注解,然后使用AOP在运行时切换MongoTemplate。

java 复制代码
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class DynamicDataSourceAspect {

    @Autowired
    private ApplicationContext applicationContext;

    @Around("@annotation(UseDataSource)")
    public Object switchDataSource(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        UseDataSource useDataSource = methodSignature.getMethod().getAnnotation(UseDataSource.class);
        MongoTemplate mongoTemplate = (MongoTemplate) applicationContext.getBean(useDataSource.value());

        try {
            MongoTemplateContextHolder.setMongoTemplate(mongoTemplate);
            return joinPoint.proceed();
        } finally {
            MongoTemplateContextHolder.clear();
        }
    }
}

定义注解和上下文持有者类:

java 复制代码
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface UseDataSource {
    String value();
}

public class MongoTemplateContextHolder {

    private static final ThreadLocal<MongoTemplate> CONTEXT = new ThreadLocal<>();

    public static void setMongoTemplate(MongoTemplate mongoTemplate) {
        CONTEXT.set(mongoTemplate);
    }

    public static MongoTemplate getMongoTemplate() {
        return CONTEXT.get();
    }

    public static void clear() {
        CONTEXT.remove();
    }
}

在使用时,通过注解指定数据源:

java 复制代码
@Service
public class MyService {

    @Autowired
    private MongoTemplate primaryMongoTemplate;

    @Autowired
    private MongoTemplate secondaryMongoTemplate;

    @UseDataSource("primaryMongoTemplate")
    public void usePrimaryDataSource() {
        MongoTemplate mongoTemplate = MongoTemplateContextHolder.getMongoTemplate();
        // 使用primaryMongoTemplate进行操作
    }

    @UseDataSource("secondaryMongoTemplate")
    public void useSecondaryDataSource() {
        MongoTemplate mongoTemplate = MongoTemplateContextHolder.getMongoTemplate();
        // 使用secondaryMongoTemplate进行操作
    }
}
方法二:直接在代码中切换数据源

你也可以直接在代码中注入多个MongoTemplate,并根据需要选择使用。

java 复制代码
@Service
public class MyService {

    @Autowired
    private MongoTemplate primaryMongoTemplate;

    @Autowired
    private MongoTemplate secondaryMongoTemplate;

    public void someMethod(boolean usePrimary) {
        MongoTemplate mongoTemplate = usePrimary ? primaryMongoTemplate : secondaryMongoTemplate;
        // 使用mongoTemplate进行操作
    }
}

这种方法比较简单直接,但需要在代码中显式选择数据源,适用于数据源切换逻辑较简单的场景。

相关推荐
一米阳光86612 小时前
软考(中级)软件设计师核心笔记(3)数据库系统——概念、数据库设计
数据库·笔记·职场发展·软考·软件设计师
蓝斯4972 小时前
[原创]《C#高级GDI+实战:从零开发一个流程图》第章:增加贝塞尔曲线,上、下、左、右连接点
java·c#·流程图
前端工作日常3 小时前
我学习到的Java 的 Service 分层:itf 和 impl 到底是什么?
java·后端
奈斯先生Vector3 小时前
告别工具碎片化:基于 Nano Banana 全模态 AI 聚合架构搭建“文本-图像-视频”自动化协同生产线
运维·数据库·人工智能·架构·自动化·aigc·音视频
都叫我大帅哥3 小时前
Spring @Transactional 注解完全指南
java·spring
Java成神之路-4 小时前
G1 垃圾回收器 :SATB + TAMS核心机制深度解析
java·jvm
前端工作日常4 小时前
我学习到的JIT即时编译与机器码缓存失效
java·后端
带刺的坐椅4 小时前
Solon 的 10 种 HTTP 服务器:改一行依赖,换一个引擎
java·solon·jetty·undertow·mcp-server·htttp
建筑工程企业管理系统5 小时前
erp工程项目管理系统落地价值:实现工程多项目成本精细化核算与管控
大数据·数据库·人工智能
xcLeigh5 小时前
Go入门:变量声明的五种方式详解
java·开发语言·golang