dynamic动态数据源编码切换数据源

系列文章目录



前言

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。
在这里插入图片描述


dynamic特性

支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。

支持数据库敏感配置信息 加密(可自定义) ENC()。

支持每个数据库独立初始化表结构schema和数据库database。

支持无数据源启动,支持懒加载数据源(需要的时候再创建连接)。

支持 自定义注解 ,需继承DS(3.2.0+)。

提供并简化对Druid,HikariCp,BeeCp,Dbcp2的快速集成。

提供对Mybatis-Plus,Quartz,ShardingJdbc,P6sy,Jndi等组件的集成方案。

提供 自定义数据源来源 方案(如全从数据库加载)。

提供项目启动后 动态增加移除数据源 方案。

提供Mybatis环境下的 纯读写分离 方案。

提供使用 spel动态参数 解析数据源方案。内置spel,session,header,支持自定义。

支持 多层数据源嵌套切换 。(ServiceA >>> ServiceB >>> ServiceC)。

提供 基于seata的分布式事务方案 。

提供 本地多数据源事务方案。

约定

本框架只做 切换数据源 这件核心的事情,并不限制你的具体操作,切换了数据源可以做任何CRUD。

配置文件所有以下划线 _ 分割的数据源 首部 即为组的名称,相同组名称的数据源会放在一个组下。

切换数据源可以是组名,也可以是具体数据源名称。组名则切换时采用负载均衡算法切换。

默认的数据源名称为 master ,你可以通过 spring.datasource.dynamic.primary 修改。

方法上的注解优先于类上注解。

DS支持继承抽象类上的DS,暂不支持继承接口上的DS。
为监控而生的数据库连接池

https://github.com/alibaba/druid

一个基于springboot的快速集成多数据源的启动器

https://github.com/baomidou/dynamic-datasource-spring-boot-starter

dynamic动态数据源集成druid实现多数据源

https://www.javacui.com/DB/727.html

在上面示例中,我们通过注解来实现数据源的切换,但是在分布式的模块代码,或者一些小的工程中,代码分部是按包划分的非常合理的,如果通过注解,这将花费很大的精力来做这件事。

如果我们只是想编码实现读写分离,第二个只读库是后来加的,要编码读取只读库,那要改动很多代码。

下面,我们通过手工切换数据源,然后通过Spring的切面来实现统一手工切换数据源,首先是Dao层不需要注解了

package com.example.demo.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@Service
public class TestDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    public String getDb1(){
        return jdbcTemplate.queryForMap("select name from user where id=1").get("name").toString();
    }
    public void update1(){
        jdbcTemplate.update("update user set name='修改 1' where id=1");
    }
}

编码切面类,实现根据指定包下方法的名字(不限参数)来手动切换数据源

package com.example.demo.config;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Aspect
@Order(Ordered.LOWEST_PRECEDENCE - 1)
@Component
public class DataSourceInterceptor {
    @Before("execution(* *..dao.*.select*(..)) " +
            "|| execution(* *..dao.*.get*(..)) " +
            "|| execution(* *..dao.*.count*(..)) " +
            "|| execution(* *..service.*.list*(..))")
    public void setReadDataSourceType() {
        DynamicDataSourceContextHolder.push("slave");
        System.out.println("dataSource切换到:slave");
    }
    @Before("execution(* *..dao.*.insert*(..)) " +
            "|| execution(* *..dao.*.update*(..)) " +
            "|| execution(* *..dao.*.delete*(..)) " +
            "|| execution(* *..dao.*.add*(..)) " +
            "|| execution(* *..dao.*.save*(..))")
    public void setWriteDataSourceType() {
        DynamicDataSourceContextHolder.push("master");
        System.out.println("dataSource切换到:master");
    }
    @AfterReturning("execution(* *..service.*.*(..))")
    public void clearDataSourceType() {
        DynamicDataSourceContextHolder.clear();
    }
}

这里的执行顺序,我们定义为了最高级别,所以这个切面会最先执行,比如你执行方法名字前缀为get的方法,就会切换到slave数据源。

  • 25
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,这是一个比较具体的技术问题。首先,Spring Boot可以通过配置多个数据源来实现多数据源切换。其次,可以使用AOP技术,在方法执行前动态切换数据源。以下是一些关键的代码片段: 1. 在application.properties文件中配置多个数据源 ``` spring.datasource.primary.url=jdbc:mysql://localhost:3306/db1 spring.datasource.primary.username=user1 spring.datasource.primary.password=pass1 spring.datasource.secondary.url=jdbc:mysql://localhost:3306/db2 spring.datasource.secondary.username=user2 spring.datasource.secondary.password=pass2 ``` 2. 创建多个数据源的Bean ``` @Configuration public class DataSourceConfig { @Bean(name = "primaryDataSource") @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(); } } ``` 3. 创建动态数据源并设置默认数据源 ``` @Configuration public class DynamicDataSourceConfig { @Autowired @Qualifier("primaryDataSource") private DataSource primaryDataSource; @Autowired @Qualifier("secondaryDataSource") private DataSource secondaryDataSource; @Bean(name = "dynamicDataSource") public DataSource dynamicDataSource() { DynamicDataSource dynamicDataSource = new DynamicDataSource(); Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put(DataSourceType.PRIMARY.name(), primaryDataSource); targetDataSources.put(DataSourceType.SECONDARY.name(), secondaryDataSource); dynamicDataSource.setTargetDataSources(targetDataSources); dynamicDataSource.setDefaultTargetDataSource(primaryDataSource); return dynamicDataSource; } @Bean public JdbcTemplate jdbcTemplate() { return new JdbcTemplate(dynamicDataSource()); } } ``` 4. 创建AOP切面,在方法执行前根据注解切换数据源 ``` @Aspect @Component public class DataSourceAspect { @Autowired @Qualifier("dynamicDataSource") private DataSource dynamicDataSource; @Pointcut("@annotation(com.example.demo.datasource.DataSource)") public void dataSourcePointCut() {} @Before("dataSourcePointCut()") public void before(JoinPoint joinPoint) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); DataSource dataSource = signature.getMethod().getAnnotation(DataSource.class); if (dataSource != null) { DataSourceType dataSourceType = dataSource.value(); DynamicDataSourceContextHolder.setDataSourceType(dataSourceType.name()); } } @After("dataSourcePointCut()") public void after(JoinPoint joinPoint) { DynamicDataSourceContextHolder.clearDataSourceType(); } } ``` 5. 在需要切换数据源的方法上添加注解 ``` @DataSource(DataSourceType.SECONDARY) public List<User> listUsers() { return jdbcTemplate.query("SELECT * FROM user", new BeanPropertyRowMapper<>(User.class)); } ``` 这样就可以实现动态切换数据源了。希望能够帮到你!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java毕设王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值