springboot添加多数据源的方法实例教程

 更新时间:2023年09月12日 10:51:51   作者:清风怎不知意  
这篇文章主要给大家介绍了关于springboot添加多数据源方法的相关资料,在实际开发中经常可能遇到在一个应用中可能要访问多个数据库多的情况,需要的朋友可以参考下

前言

Spring Boot可以通过配置多个数据源来支持多数据源访问,以下是一个基本的多数据源配置实例:

添加多数据源的配置类

创建一个配置类来配置多个数据源,可以使用@Configuration和@Primary注解来标识主数据源,示例代码如下:

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

在这个配置类中,我们定义了两个数据源,一个是主数据源,一个是次要数据源。我们使用@ConfigurationProperties注解来设置每个数据源的配置参数。

在application.yml中添加数据源配置

添加application.yml配置文件,并在文件中添加多个数据源的配置信息,例如:

spring:
  datasource:
    primary:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/test1
      username: root
      password: root
    secondary:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/test2
      username: root
      password: root

我们使用了Spring Boot的默认配置规则,通过指定数据源的名称和属性前缀来配置每个数据源。

配置JdbcTemplate来访问多个数据源

现在我们已经定义了两个数据源,我们需要配置JdbcTemplate来访问它们。我们可以在使用JdbcTemplate的每个方法中指定要使用的数据源,示例代码如下:

@Repository
public class UserRepository {
    @Autowired
    @Qualifier("primaryDataSource")
    private DataSource primaryDataSource;
    @Autowired
    @Qualifier("secondaryDataSource")
    private DataSource secondaryDataSource;
    public List<User> getUsersFromPrimary() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(primaryDataSource);
        List<User> users = jdbcTemplate.query("SELECT * FROM users", new BeanPropertyRowMapper(User.class));
        return users;
    }
    public List<User> getUsersFromSecondary() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(secondaryDataSource);
        List<User> users = jdbcTemplate.query("SELECT * FROM users", new BeanPropertyRowMapper(User.class));
        return users;
    }
}

我们在注入JdbcTemplate之前使用@Autowired注解将每个数据源注入到存储库类中。然后,我们可以在每个方法中使用JdbcTemplate来访问不同的数据源。

这是一个基本的多数据源配置实例,你可以在此基础上进一步调整以满足你的具体需求。

如果你使用的是MyBatis框架,你可以使用MyBatis的动态数据源来实现多数据源配置,具体步骤如下

定义数据源配置类

首先,你需要定义一个数据源配置类来读取和解析配置文件,然后根据配置创建数据源并将其添加到数据源列表中,示例代码如下:

@Configuration
public class DataSourceConfig {
    @Value("${spring.datasource.type}")
    private Class<? extends DataSource> dataSourceType;
    @Bean(name = "masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().type(dataSourceType).build();
    }
    @Bean(name = "slaveDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource slaveDataSource() {
        return DataSourceBuilder.create().type(dataSourceType).build();
    }
    @Bean(name = "dynamicDataSource")
    public DataSource dynamicDataSource() {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource());
        targetDataSources.put(DataSourceType.SLAVE.name(), slaveDataSource());
        dynamicDataSource.setTargetDataSources(targetDataSources);
        dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
        return dynamicDataSource;
    }
}

在这个配置类中,我们使用@ConfigurationProperties注解来读取每个数据源的配置信息,然后使用DataSourceBuilder创建数据源对象。接着,我们使用DynamicDataSource类来管理多个数据源,将所有数据源添加到targetDataSources中并设置默认数据源为masterDataSource。

实现动态数据源

接下来,你需要实现一个动态数据源,它可以根据需要选择不同的数据源,示例代码如下:

public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DynamicDataSourceContextHolder.getDataSourceType();
    }
}

我们继承了AbstractRoutingDataSource类,覆盖了它的determineCurrentLookupKey()方法来获取当前线程所需的数据源类型,并返回数据源名称。

实现数据源上下文

最后,你需要创建一个数据源上下文来保存当前线程所需的数据源类型,示例代码如下:

public class DynamicDataSourceContextHolder {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
    public static void setDataSourceType(String dataSourceType) {
        contextHolder.set(dataSourceType);
    }
    public static String getDataSourceType() {
        return contextHolder.get();
    }
    public static void clearDataSourceType() {
        contextHolder.remove();
    }
}

我们使用了ThreadLocal来保存当前线程所需的数据源类型。你可以在需要访问不同数据源的方法中调用setDataSourceType()方法来设置当前线程所需的数据源类型,调用clearDataSourceType()方法来清除上下文。

最后,在你的MyBatis配置文件中,你可以使用${}占位符引用定义的动态数据源,示例代码如下:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dynamicDataSource"/>
    <property name="typeAliasesPackage" value="com.example.model"/>
</bean>

我们将MyBatis的SqlSessionFactoryBean中的dataSource属性设置为定义的动态数据源dynamicDataSource即可。

切换数据源

最后,你可以在需要访问不同数据源的方法中调用DynamicDataSourceContextHolder.setDataSourceType()方法来设置当前线程所需的数据源类型。例如,你可以定义一个注解来标识使用哪个数据源,然后在方法上加上这个注解即可自动切换数据源。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
    DataSourceType value() default DataSourceType.MASTER;
}
@Aspect
@Component
public class DynamicDataSourceAspect {
    @Pointcut("@annotation(com.example.annotation.DataSource)")
    public void dataSourcePointcut() {
    }
    @Before("dataSourcePointcut()")
    public void before(JoinPoint joinPoint) {
        DataSource dataSource = getDataSource(joinPoint);
        if (dataSource != null) {
            DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
        }
    }
    @After("dataSourcePointcut()")
    public void after(JoinPoint joinPoint) {
        DynamicDataSourceContextHolder.clearDataSourceType();
    }
    private DataSource getDataSource(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        if (method.isAnnotationPresent(DataSource.class)) {
            return method.getAnnotation(DataSource.class);
        }
        return null;
    }
}

在这个例子中,我们定义了一个@DataSource注解来标识使用哪个数据源,然后使用AOP来自动切换数据源。在DynamicDataSourceAspect类中,我们使用@Pointcut注解来定义切点,然后使用@Before和@After注解来分别在方法调用前和方法调用后切换数据源。在切换数据源时,我们可以通过getDataSource()方法获取方法上的@DataSource注解,并使用注解中定义的数据源类型来设置当前线程所需的数据源类型。

总结

到此这篇关于springboot添加多数据源方法的文章就介绍到这了,更多相关springboot添加多数据源内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring注解@Configuration和@Component区别详解

    Spring注解@Configuration和@Component区别详解

    @Component和@Configuration都可以作为配置类,之前一直都没觉得这两个用起来有什么差别,可能有时程序跑的和自己想的有所区别也没注意到,下面这篇文章主要给大家介绍了关于Spring注解@Configuration和@Component区别的相关资料,需要的朋友可以参考下
    2023-04-04
  • Spring Boot整合EhCache的步骤详解

    Spring Boot整合EhCache的步骤详解

    EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认CacheProvider。这篇文章主要介绍了Spring Boot整合EhCache的步骤详解,需要的朋友可以参考下
    2020-02-02
  • Java中CopyOnWriteArrayList的使用解析

    Java中CopyOnWriteArrayList的使用解析

    这篇文章主要介绍了Java中CopyOnWriteArrayList的使用解析,CopyOnWriteArrayList适合使用在读操作远远大于写操作的场景里,比如缓存,它不存在扩容的概念,每次写操作都要复制一个副本,在副本的基础上修改后改变Array引用,需要的朋友可以参考下
    2023-12-12
  • Java线程休眠的5种方法

    Java线程休眠的5种方法

    这篇文章主要介绍了Java线程休眠的5种方法,分别是Thread.sleep、TimeUnit、wait、Condition、LockSupport,下面文章将对这五种方法进行详细讲解,需要的小伙伴可以参考一下
    2022-05-05
  • Shiro集成Spring之注解示例详解

    Shiro集成Spring之注解示例详解

    Shiro想必大家都知道了,是目前使用率要比spring security都要多的一个权限框架,下面这篇文章主要给大家介绍了关于Shiro集成Spring之注解的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-09-09
  • Spring Boot日志基础使用之如何设置日志级别

    Spring Boot日志基础使用之如何设置日志级别

    这篇文章主要介绍了Spring Boot日志基础使用设置日志级别的方法,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • jdbc实现图书馆借阅系统

    jdbc实现图书馆借阅系统

    这篇文章主要为大家详细介绍了jdbc实现图书馆借阅系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • 新手必备的IDEA常用设置总结

    新手必备的IDEA常用设置总结

    今天给大家总结了一些IDEA的常用设置,文中有非常详细的图文介绍,对正在学习使用IDEA的小伙伴们很有帮助,需要的朋友可以参考下
    2021-05-05
  • Java NIO无法绑定指定IP和端口解决方案

    Java NIO无法绑定指定IP和端口解决方案

    这篇文章主要介绍了Java NIO无法绑定指定IP和端口解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • SpringCloud整合Activiti过程中的踩坑记录

    SpringCloud整合Activiti过程中的踩坑记录

    由于项目需要,最近开始在项目Spring boot中集成工作流引擎Activiti,由于第一次集成,一路上步步都是坑,所以这篇文章主要给大家介绍了关于SpringCloud整合Activiti过程中所遇到的踩坑记录,需要的朋友可以参考下
    2021-09-09

最新评论