SpringBoot多数据源的两种实现方式实例

下面我就为你详细讲解一下“SpringBoot多数据源的两种实现方式实例”的完整攻略。

SpringBoot多数据源的两种实现方式实例

为什么需要多数据源

在实际开发中,我们可能会遇到这样的情况:业务系统需要同时连接多个数据库进行数据操作。此时单数据源的方式已无法满足需求,必须使用多数据源来进行解决。

方案一:使用@Primary注解

1.添加多数据源配置项

application.yml文件中添加多个数据源配置项,例如:

spring:
  datasource:
    primary:
      url: jdbc:mysql://localhost:3306/primary?useUnicode=true&characterEncoding=UTF-8&useSSL=false
      username: root
      password: 123456
    secondary:
      url: jdbc:mysql://localhost:3306/secondary?useUnicode=true&characterEncoding=UTF-8&useSSL=false
      username: root
      password: 123456

2.创建两个数据源Bean

DataSourceConfig类中创建两个数据源Bean,代码如下:

@Configuration
public class DataSourceConfig {

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

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

}

需要注意的是,@Primary注解表示优先使用该数据源,可以避免出现无法确定使用哪个数据源的情况。

3.配置JdbcTemplate

JdbcTemplateConfig类中配置两个JdbcTemplate,代码如下:

@Configuration
public class JdbcTemplateConfig {

    @Bean(name = "primaryJdbcTemplate")
    public JdbcTemplate primaryJdbcTemplate(
            @Qualifier("primaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    @Bean(name = "secondaryJdbcTemplate")
    public JdbcTemplate secondaryJdbcTemplate(
            @Qualifier("secondaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

}

4.编写访问多数据源的Controller

最后我们编写一个Controller来测试两个数据源是否能正常访问。

@RestController
public class UserController {

    @Autowired
    @Qualifier("primaryJdbcTemplate")
    private JdbcTemplate primaryJdbcTemplate;

    @Autowired
    @Qualifier("secondaryJdbcTemplate")
    private JdbcTemplate secondaryJdbcTemplate;

    @GetMapping("/users")
    public List<Map<String, Object>> getUsers() {
        String sql = "select * from user";
        List<Map<String, Object>> userList = primaryJdbcTemplate.queryForList(sql);
        sql = "select * from user";
        List<Map<String, Object>> userList2 = secondaryJdbcTemplate.queryForList(sql);
        userList.addAll(userList2);
        return userList;
    }

}

上面这个Controller中,我们使用了@Qualifier注解来指定使用哪个JdbcTemplate

方案二:动态切换数据源

1.添加多数据源配置项

与方案一相同,在application.yml文件中添加多个数据源配置项。

2.创建自定义注解

datasource包下创建一个自定义注解DataSourceType

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

3.创建数据源切换AOP切面

创建一个DataSourceAspect类,代码如下:

@Component
@Aspect
public class DataSourceAspect {

    @Pointcut("@annotation(com.example.datasource.DataSourceType)")
    public void dataSourcePointCut() { }

    @Around("dataSourcePointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        DataSourceType dataSourceType = signature.getMethod().getAnnotation(DataSourceType.class);
        if (null == dataSourceType) {
            DynamicDataSourceContextHolder.clearDataSourceType();
        } else {
            DynamicDataSourceContextHolder.setDataSourceType(dataSourceType.value());
        }
        try {
            return point.proceed();
        } finally {
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }
}

该类使用了@Aspect注解来表示它是一个切面类,同时使用了@Component注解来将它加入到Spring容器中。

@Pointcut注解用来定义切点,该处定义了所有使用了@DataSourceType注解的方法或类。

@Around注解用来定义环绕通知,当使用了@DataSourceType注解时,切面会根据注解所指定的数据源类型来切换数据源。

4.创建自定义数据源

创建一个DynamicDataSource类,该类继承AbstractRoutingDataSource,并重写determineCurrentLookupKey()方法来动态切换数据源。

public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceContextHolder.getDataSourceType();
    }

}

5.创建动态数据源配置

@Configuration
public class DynamicDataSourceConfig {

    @Bean("primaryDataSource")
    @ConfigurationProperties("spring.datasource.primary")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean("secondaryDataSource")
    @ConfigurationProperties("spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean
    public DynamicDataSource dataSource(@Qualifier("primaryDataSource") DataSource primaryDataSource,
                                         @Qualifier("secondaryDataSource") DataSource secondaryDataSource) {
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("primary", primaryDataSource);
        targetDataSources.put("secondary", secondaryDataSource);
        DynamicDataSource dataSource = new DynamicDataSource();
        dataSource.setTargetDataSources(targetDataSources);
        dataSource.setDefaultTargetDataSource(primaryDataSource);
        return dataSource;
    }

}

在上述代码中,我们使用@Primary注解来指定默认使用的数据源,同时将primaryDataSourcesecondaryDataSource注入到DynamicDataSource类中,最终返回一个DynamicDataSource实例。

6.配置JdbcTemplate

与方案一相同,在JdbcTemplateConfig类中配置两个JdbcTemplate

7.编写使用切面的Controller

@RestController
public class UserController {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @GetMapping("/users")
    @DataSourceType("secondary")
    public List<Map<String, Object>> getUsers() {
        String sql = "select * from user";
        return jdbcTemplate.queryForList(sql);
    }

}

上面这个Controller中,我们使用了@DataSourceType注解来指定使用哪个数据源。

至此,我们已经完成了基于切面的动态数据源切换方案。

总结

本文为你详细讲解了SpringBoot多数据源的两种实现方式。方案一使用了@Primary注解来指定使用哪个数据源,方案二则使用了AOP切面来动态切换数据源。无论你选择哪种方案,都需要了解的是多数据源的加载方式,并且需要配置JdbcTemplate才能够操作多个数据源。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot多数据源的两种实现方式实例 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • 一起来了解Java的File类和IO流

    一起来了解Java的File类和IO流 File类 Java中的File类是一个用于操作文件和目录的类。使用File类可以实现文件的创建、删除、重命名、遍历等操作。File类的构造函数可以传入一个文件路径字符串或者一个URI,用于表示文件或者目录的路径。下面是一些常用的File类的操作示例: 创建和删除文件 File file = new File(&quo…

    Java 2023年5月19日
    00
  • springboot添加https服务器的方法

    关于“springboot添加https服务器的方法”的完整攻略,以下是详细步骤和示例说明: 1.获取https证书 首先需要获取一个https证书。可以通过自己生成证书,也可以通过第三方机构购买证书。这里以通过免费的Let’s Encrypt获取证书为例。以下是获取过程: 安装Certbot客户端 Certbot是Let’s Encrypt官方提供的一个证…

    Java 2023年5月23日
    00
  • 如何通过Java实现加密、解密Word文档

    要通过Java实现加密和解密Word文档,需要进行以下步骤: 添加依赖在Java项目中,需要添加依赖,包括poi-ooxml和poi-ooxml-schemas。可以在Maven、Gradle等项目管理工具中添加依赖,也可以直接在项目中使用jar包。 加密Word文档加密Word文档需要使用Apache POI库。首先需要创建一个POIFSFileSyste…

    Java 2023年5月26日
    00
  • 通过简单方法实现spring boot web项目

    下面是详细讲解如何通过简单方法实现SpringBoot Web项目的完整攻略。 步骤一:创建SpringBoot项目 首先,在Eclipse或IDEA中创建一个空的Maven项目,并在pom.xml中添加以下依赖: <dependency> <groupId>org.springframework.boot</groupId&g…

    Java 2023年5月15日
    00
  • Java基础类之ArrayUtils工具类详解

    Java基础类之ArrayUtils工具类详解 ArrayUtils 工具类是 Apache Commons Lang 库中的一部分,提供了很多实用的用于处理数组的方法。本节将详细介绍 ArrayUtils 工具类的常用方法。 导入 ArrayUtils 首先需要明确的是,要使用 ArrayUtils 工具类,需要在 Java 代码中导入对应的包。可以使用以…

    Java 2023年5月26日
    00
  • Java 定时器的多种实现方式

    Java 定时器的多种实现方式 前言 在 Java 开发中,我们经常需要编写定时任务,如定时备份、定时发送消息等。这些任务需要在指定时间点或时间间隔内执行。而实现这些定时任务的方法有多种,本文将一一介绍这些方式,包括 Java 内置定时器、定时线程池、Quartz 框架以及 Spring 自带的定时任务。 Java 内置定时器 Java 内置了一个 Time…

    Java 2023年5月18日
    00
  • SpringBoot快速入门及起步依赖解析(实例详解)

    SpringBoot快速入门及起步依赖解析 SpringBoot是一个快速构建基于Spring的应用程序的框架。在本文中,我们将为您介绍如何快速入门以及如何使用起步依赖项。 快速入门 在使用SpringBoot之前,我们需要首先配置Maven或者Gradle来构建我们的应用程序。这里我们以Maven为例。 创建一个maven项目 使用Maven创建一个新项目…

    Java 2023年5月15日
    00
  • Java操作Mysql的方法

    关于Java操作MySQL的方法,需要掌握以下几点: 导入数据库驱动程序 建立数据库连接 创建statement对象,执行SQL语句 处理查询结果集 关闭各种连接 下面将详细介绍这些步骤以及如何实现它们。 导入数据库驱动程序 在Java中操作MySQL,需要先导入MySQL的JDBC驱动程序。如果你使用的是Maven等依赖管理工具,可以直接在pom.xml中…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部