在MongoDB中配置和使用多数据源主要涉及以下几个步骤:
-
定义多个数据源的配置:
- 在应用程序的配置文件中,定义多个MongoDB的数据源,例如在Spring Boot中可以通过application.yml或application.properties文件进行配置。
-
创建多个MongoTemplate Bean:
- 使用Spring框架的Java配置类,创建多个
MongoTemplate
Bean,每个Bean对应一个数据源。
- 使用Spring框架的Java配置类,创建多个
-
使用动态切换数据源的方式:
- 使用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进行操作
}
}
这种方法比较简单直接,但需要在代码中显式选择数据源,适用于数据源切换逻辑较简单的场景。