Java 工程调用多个数据库

在实际开发中,有时我们需要在同一个 Java 工程中连接并操作多个不同的数据库。这种需求可能是因为不同的数据存储有不同的用途或者需求,比如一个数据库用于用户认证,另一个数据库用于存储业务数据等。在这篇文章中,我们将介绍如何在 Java 工程中调用多个数据库,并提供代码示例。

数据源配置

首先,我们需要在 application.properties 或者 application.yml 中配置多个数据源的连接信息。以 Spring Boot 为例,我们可以配置两个数据源如下:

# application.properties
# 第一个数据源
spring.datasource.url=jdbc:mysql://localhost:3306/db1
spring.datasource.username=user1
spring.datasource.password=password1
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# 第二个数据源
datasource2.url=jdbc:mysql://localhost:3306/db2
datasource2.username=user2
datasource2.password=password2
datasource2.driver-class-name=com.mysql.cj.jdbc.Driver

数据源配置类

接着,我们需要创建数据源配置类,用于加载多个数据源的配置信息,并提供对外的数据源对象。我们可以通过 @Configuration@Bean 注解来实现:

@Configuration
public class DataSourceConfig {

    @Primary
    @Bean(name = "dataSource1")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource1() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "dataSource2")
    @ConfigurationProperties(prefix = "datasource2")
    public DataSource dataSource2() {
        return DataSourceBuilder.create().build();
    }
}

数据源路由

为了在 Java 工程中调用多个数据库,我们需要一个数据源路由的机制来根据具体的需求选择不同的数据源。可以通过 AOP 切面和 ThreadLocal 来实现数据源的动态切换。

@Aspect
@Component
public class DataSourceAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void before(JoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        if (method.isAnnotationPresent(DataSource.class)) {
            DataSource dataSource = method.getAnnotation(DataSource.class);
            DynamicDataSourceContextHolder.setDataSource(dataSource.value());
        }
    }

    @After("execution(* com.example.service.*.*(..))")
    public void after() {
        DynamicDataSourceContextHolder.clearDataSource();
    }
}

public class DynamicDataSourceContextHolder {

    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();

    public static void setDataSource(String dataSource) {
        CONTEXT_HOLDER.set(dataSource);
    }

    public static String getDataSource() {
        return CONTEXT_HOLDER.get();
    }

    public static void clearDataSource() {
        CONTEXT_HOLDER.remove();
    }
}

数据源注解

为了在服务层方法上指定使用哪个数据源,我们可以自定义一个 @DataSource 注解:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
    String value() default "dataSource1";
}

服务层方法

最后,在服务层方法中使用 @DataSource 注解来指定调用哪个数据源:

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    @DataSource("dataSource1")
    public User getUserFromDataSource1(Long id) {
        return userDao.getUser(id);
    }

    @DataSource("dataSource2")
    public User getUserFromDataSource2(Long id) {
        return userDao.getUser(id);
    }
}

@Repository
public interface UserDao {
    User getUser(Long id);
}

总结

通过上面的配置和代码示例,我们可以在 Java 工程中调用多个数据库,并且根据具体的需求切换数据源。这种方式能够灵活应对不同的业务场景,提高系统的可扩展性和灵活性。希望本文对你有所帮助,谢谢阅读!

pie
    title 数据库使用比例
    "数据库1" : 40
    "数据库2" : 60
erDiagram
    CUSTOMER ||--o{ ORDER : has
    ORDER ||--|{ LINE-ITEM : contains
    CUSTOMER }|..|{ ADDRESS : "delivery address"