SpringBoot动态切换数据源

这篇具有很好参考价值的文章主要介绍了SpringBoot动态切换数据源。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 Spring提供一个DataSource实现类用于动态切换数据源——AbstractRoutingDataSource

pom.xml

<dependencies>
    <!--meiyouyemeishi-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.3.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.2.15</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter-test</artifactId>
        <version>3.0.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <excludes>
                    <exclude>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                    </exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>

大概的项目结构

SpringBoot动态切换数据源,spring boot,java,spring

SpringBoot动态切换数据源,spring boot,java,spring

@RestController
public class TestController {

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ApplicationContext context;
    @RequestMapping("/test01")
    //@Transactional
    public Object test01(){
        Student student=new Student();
        student.setName("db1");
        student.setAge("18");
        student.setGender("男");
        int i = studentMapper.insertStudent(student);
        User user=new User(null,"db2", "123456");
        int j = userMapper.insertUser(user);

        return i+j;
    }


    @RequestMapping("/test02")
    public Object test02(){
        Student student=new Student();
        student.setName("db1");
        student.setAge("18");
        student.setGender("男");
        int i = studentMapper.insertStudent(student);
        return i;
    }


    @RequestMapping("/test03")
    public Object test03(){
        User user=new User(null,"db2", "123456");
        int i = userMapper.insertUser(user);
        return i;
    }
}
package com.example.demo3.datasource;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author hrui
 * @date 2023/11/2 4:36
 */
@Component
@Aspect
@Order(-100)
public class DataSourceAop {



    @Pointcut("execution(* com.example.demo3.mapper.*.*(..)) && @annotation(com.example.demo3.datasource.DataSourceTypeAnno)")
    public void dataSourcePointcut(){}

    @Around("dataSourcePointcut()")
    public Object doAround(ProceedingJoinPoint pjp){

        MethodSignature methodSignature = (MethodSignature)pjp.getSignature();
        Method method = methodSignature.getMethod();
        DataSourceTypeAnno typeAnno = method.getAnnotation(DataSourceTypeAnno.class);
        String value = typeAnno.value();

        switch (value){
            case "db1":DataSourceUtil.setDB("db1");break;
            case "db2":DataSourceUtil.setDB("db2");break;
        }

        Object result = null ;

        try {
            result = pjp.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }finally {
            DataSourceUtil.setDB("db1");
        }
        return result;
    }
}

注意:这两个事务管理器,并不能处理分布式事务

@Configuration
public class DataSourceConfig {

        /**
         * 数据源1
         * spring.datasource.db1:application.properteis中对应属性的前缀
         * @return
         */
        @Bean(name = "db1")
        @ConfigurationProperties(prefix = "spring.datasource.db1")
        public DataSource dataSourceOne() {
            //return DataSourceBuilder.create().build();
            return  DruidDataSourceBuilder.create().build();
        }//如果选druid连接池

        /**
         * 数据源2
         * spring.datasource.db2:application.properteis中对应属性的前缀
         * @return
         */
        @Bean(name = "db2")
        @ConfigurationProperties(prefix = "spring.datasource.db2")
        public DataSource dataSourceTwo() {
            //return DataSourceBuilder.create().build();

            return  DruidDataSourceBuilder.create().build();
        }

        /**
         * 动态数据源: 通过AOP在不同数据源之间动态切换
         * @return
         */
        @Bean(name = "dynamicDataSource")
        @Primary
        public DataSource dynamicDataSource(@Qualifier("db1") DataSource db1, @Qualifier("db2") DataSource db2) {
            DynamicDataSource dynamicDataSource = new DynamicDataSource();
            // 默认数据源
            dynamicDataSource.setDefaultTargetDataSource(db1);
            // 配置多数据源
            Map<Object, Object> dsMap = new HashMap<>();
            dsMap.put("db1", db1);
            dsMap.put("db2", db2);
            //所有数据源

            dynamicDataSource.setTargetDataSources(dsMap);
            return dynamicDataSource;
        }

//        /**
//         * 配置@Transactional注解
//         * @return
//         */
//        @Bean
//        public PlatformTransactionManager transactionManager(@Qualifier("dynamicDataSource") DataSource dynamicDataSource) {  这个有问题
//            return new DataSourceTransactionManager(dynamicDataSource);
//        }

        @Bean
        @Primary
        public PlatformTransactionManager transactionManager1(@Qualifier("db1") DataSource dynamicDataSource) {
            return new DataSourceTransactionManager(dynamicDataSource);
        }
        @Bean
        public PlatformTransactionManager transactionManager2(@Qualifier("db2") DataSource dynamicDataSource) {
            return new DataSourceTransactionManager(dynamicDataSource);
        }
}
//控制注解的生命周期,什么时候起作用
@Retention(RetentionPolicy.RUNTIME)
//注解的作用对象:  类上   方法上 变量上
@Target({ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})
public @interface DataSourceTypeAnno {
    String value() default "db1";
}
public class DataSourceUtil {
    private static final ThreadLocal<String> local = new ThreadLocal();

    /**
     * 设置数据源名
     * @param dbType
     */
    public static void setDB(String dbType) {
        local.set(dbType);
    }

    /**
     * 获取数据源名
     * @return
     */
    public static String getDB() {
        return local.get();
    }




    /**
     * 清除数据源名
     */
    public static void clearDB() {
        local.remove();
    }
}
@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        log.info("动态获取数据源——{}",DataSourceUtil.getDB());
        return DataSourceUtil.getDB();
    }
}

链接:https://pan.baidu.com/s/1ymxeKYkI-cx7b5nTQX0KWQ 
提取码:6bii 
--来自百度网盘超级会员V4的分享                文章来源地址https://www.toymoban.com/news/detail-738449.html

到了这里,关于SpringBoot动态切换数据源的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot——动态数据源(多数据源自动切换)

    日常的业务开发项目中只会配置一套数据源,如果需要获取其他系统的数据往往是通过调用接口, 或者是通过第三方工具比如kettle将数据同步到自己的数据库中进行访问。 但是也会有需要在项目中引用多数据源的场景。比如如下场景: 自研数据迁移系统,至少需要新、老两

    2024年02月16日
    浏览(31)
  • SpringBoot动态切换数据源

      Spring提供一个DataSource实现类用于动态切换数据源—— AbstractRoutingDataSource pom.xml 大概的项目结构 注意:这两个事务管理器,并不能处理分布式事务 链接:https://pan.baidu.com/s/1ymxeKYkI-cx7b5nTQX0KWQ  提取码:6bii  --来自百度网盘超级会员V4的分享                

    2024年02月06日
    浏览(39)
  • SpringBoot从数据库读取数据数据源配置信息,动态切换数据源

            首先准备多个数据库,主库smiling-datasource,其它库test1、test2、test3         接下来,我们在主库smiling-datasource中,创建表databasesource,用于存储多数据源相关信息。表结构设计如下         创建好表之后,向表databasesource中存储test1、test2、test3三个数据库的相关配置

    2024年01月16日
    浏览(51)
  • springboot使用DynamicDataSource来动态切换数据源

    DynamicDataSource是一个数据源路由器,可以根据上下文动态选择数据源。可以在每个请求或线程中将数据源设置为当前需要使用的数据. 创建一个 DynamicDataSource 类,它继承自 AbstractRoutingDataSource 。在该类中重写**determineCurrentLookupKey()**方法,该方法返回一个字符串,用于指示当前

    2024年02月05日
    浏览(32)
  • 一种实现Spring动态数据源切换的方法

    不在现有查询代码逻辑上做任何改动,实现dao维度的数据源切换(即表维度) 节约bdp的集群资源。接入新的宽表时,通常uat验证后就会停止集群释放资源,在对应的查询服务器uat环境时需要查询的是生产库的表数据(uat库表因为bdp实时任务停止,没有数据落入),只进行服务

    2024年02月09日
    浏览(44)
  • 【Java】Spring Boot配置动态数据源

    1.1 创建动态数据源 通过实现Spring提供的AbstractRoutingDataSource类,可以实现自己的数据源选择逻辑,从而可以实现数据源的动态切换。 1.2 创建动态数据源配置类 跟配置静态多数据源一样,需要手动配置下面的三个 Bean,只不过DynamicDataSource类的targetDataSources是空的。 1.3 创建动

    2024年02月09日
    浏览(42)
  • SpringBoot整合多数据源,并支持动态新增与切换(详细教程)

    推荐文章:     1、springBoot对接kafka,批量、并发、异步获取消息,并动态、批量插入库表;     2、SpringBoot用线程池ThreadPoolTaskExecutor异步处理百万级数据;     3、java后端接口API性能优化技巧     4、SpringBoot+MyBatis流式查询,处理大规模数据,提高系统的性能和响应能力。 一

    2024年02月10日
    浏览(33)
  • spring多数据源动态切换的实现原理及读写分离的应用

    AbstractRoutingDataSource 是Spring框架中的一个抽象类,可以实现多数据源的动态切换和路由,以满足复杂的业务需求和提高系统的性能、可扩展性、灵活性。 多租户支持:对于多租户的应用,根据当前租户来选择其对应的数据源,实现租户级别的隔离和数据存储。 分库分表:为了

    2024年02月14日
    浏览(30)
  • 一种实现Spring动态数据源切换的方法 | 京东云技术团队

    不在现有查询代码逻辑上做任何改动,实现dao维度的数据源切换(即表维度) 节约bdp的集群资源。接入新的宽表时,通常uat验证后就会停止集群释放资源,在对应的查询服务器uat环境时需要查询的是生产库的表数据(uat库表因为bdp实时任务停止,没有数据落入),只进行服务

    2024年02月10日
    浏览(47)
  • SpringBoot整合Druid数据库连接池&多数据源&注解切换&动态添加

    配置好之后 Druid 会通过 DruidDataSourceAutoConfigure 自动装配 属性配置 数据源枚举 动态数据源 继承 AbstractRoutingDataSource 就可以实现动态数据源了 实现了一个动态数据源类的构造方法,主要是为了设置默认数据源,以及以Map保存的各种目标数据源。其中Map的key是设置的数据源名称

    2024年03月22日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包