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

yizhihongxing

下面我就为你详细讲解一下“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日

相关文章

  • 你应该知道的21个Java核心技术

    你应该知道的21个Java核心技术攻略 Java作为一门广泛应用于企业级系统开发的编程语言,核心技术对于开发人员非常重要。在这里,我们总结了21个Java核心技术,并提供了相应的攻略,供您参考。 1. Java基础语法 Java基础语法是Java编程的基础,掌握了这些知识,可以轻松地进入Java编程的世界。在学习Java基础语法时,我们应该注重掌握Java数…

    Java 2023年5月23日
    00
  • Java实现计算一个月有多少天和多少周

    确定一个月有多少天和多少周是一个常见的问题。在Java中可以通过一些基本的语法和时间API来实现。下面我们来详细讲解如何实现计算一个月有多少天和多少周。 计算月份天数 Java中可以使用Calendar类来计算月份天数。具体步骤如下: 获取当前时间,使用Calendar.getInstance()方法获取。例如:Calendar cal = Calendar…

    Java 2023年6月1日
    00
  • 详解如何热更新线上的Java服务器代码

    热更新线上的Java服务器代码是一项非常重要的工作,它可以帮助优化服务器运维和开发流程,从而提升系统的稳定性和可靠性。下面是我总结的详解热更新Java服务器代码的攻略: 1. 什么是热更新 所谓热更新,是指在不停机的情况下,将Java服务器代码替换成新的代码,从而实现在线上更新代码的目的。相比传统的停机更新方式,热更新更加方便快捷,不会对用户造成影响和中断服…

    Java 2023年6月16日
    00
  • 浅谈Java(SpringBoot)基于zookeeper的分布式锁实现

    浅谈Java(SpringBoot)基于zookeeper的分布式锁实现 分布式系统中的一个关键问题就是确保同一时刻只有一个进程对共享资源进行访问,否则就会导致数据一致性问题。为了解决这个问题,一种常见的解决方案是使用分布式锁。本文将介绍如何基于zookeeper实现分布式锁。 使用场景 如下场景需要使用分布式锁: 数据库事务锁的资源互斥访问 限流器计数器 …

    Java 2023年5月19日
    00
  • Java常用类之字符串相关类使用详解

    Java常用类之字符串相关类使用详解 字符串是Java语言中最常用的数据类型之一,Java提供了许多字符串相关的类来方便我们对字符串进行操作和处理。在本文中,我们将对Java字符串相关的常用类进行详解。 常用字符串类 以下是Java中常用的字符串类: String:Java中最基本的字符串类。 StringBuffer:可变的字符串类。 StringBuil…

    Java 2023年5月26日
    00
  • SSH框架网上商城项目第10战之搭建商品类基本模块

    为了方便说明,我们先假设该网上商城项目已经基本搭建完成并且有一个可以登录系统的页面。接下来,针对搭建商品类基本模块,我将按照如下步骤进行讲解: 1. 创建商品类相关的数据库表 首先,需要在数据库中创建商品类相关的表,可以根据实际需求设计表结构,以下是一个示例: CREATE TABLE `tb_category` ( `id` int(11) NOT NUL…

    Java 2023年6月15日
    00
  • Java Scala数据类型与变量常量及类和对象超详细讲解

    Java Scala数据类型与变量常量及类和对象超详细讲解 一、Java Scala数据类型 在Java Scala中,数据类型主要分为以下几种: 基本数据类型:包括整型、浮点型、布尔型和字符型等。 数组类型:包括一维数组和多维数组。 引用数据类型:包括类类型、接口类型、枚举类型和数组类型等。 下面我们分别对每种数据类型进行详细讲解: 1.1 基本数据类型 …

    Java 2023年5月26日
    00
  • Java毕业设计实战之教室预订管理系统的实现

    题目:Java毕业设计实战之教室预订管理系统的实现 一、项目背景 在大学生活中,教室预订管理系统是一个非常实用的工具。它可以帮助学生和教职工方便地预订教室,并能够快速地查看教室的占用情况和可用时间等信息。因此,在Java毕业设计中,实现一个教室预订管理系统是很有实际意义的。此项目的大致流程是:管理员对教室进行管理,学生和教职员工可以预订教室。 二、需求分析 …

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