SpringBoot+MyBatisPlus+Mysql多数据源配置(二)

多数据源配置(二):代码实现多数据源配置

由于MyBatisPlus对于MyBatis只做升级不做修改,是无条件兼容的,所以我现在建Spring的项目都是直接整合MyBatisPlus,就是为了方便快速开发。SpringBoot项目整合MyBatisPlus,配置多数据源的主从同步,跟传统的单数据源配置还是有很大的区别。关键是要做好读写分离,主库增、删、改,从库查

一、新建一个SpringBoot项目

二、导入相关依赖

<!-- aop -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- mybatis-plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.2</version>
</dependency>
<!-- alibaba的druid数据库连接池 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.4</version>
</dependency>

三、yaml中配置多数据源

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    druid:
      master:
        username: your_name
        password: your_pwd
        url: jdbc:mysql://*.*.*.*:*/*?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
        driver-class-name: com.mysql.cj.jdbc.Driver
        initialSize: 1
        minIdle: 1
        maxActive: 20
      slave:
        username: your_name
        password: your_pwd
        url: jdbc:mysql://*.*.*.*:*/*?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
        driver-class-name: com.mysql.cj.jdbc.Driver
        initialSize: 1
        minIdle: 1
        maxActive: 20

四、代码实现

1.新建一个枚举类DBTypeEnum,标识主从数据源

public enum DBTypeEnum {
    MASTER("master"), SLAVE("slave");

    private String value;
    DBTypeEnum(String value){
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}

2.多数据源切换处理类DBContextHolder

public class DBContextHolder {

    private static final ThreadLocal<DBTypeEnum> contextHolder = new InheritableThreadLocal<>();

    public static void set(DBTypeEnum dbType) {
        contextHolder.set(dbType);
    }

    public static DBTypeEnum get() {
        return contextHolder.get();
    }

    public static void master() {
        set(DBTypeEnum.MASTER);
        System.out.println("切换到master数据源");
    }

    public static void slave() {
        set(DBTypeEnum.SLAVE);
        System.out.println("切换到slave数据源");
    }

    public static void cleanAll() {
        contextHolder.remove();
    }
}

3.动态数据源MyRoutingDataSource

public class MyRoutingDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DBContextHolder.get();
    }
}

4.数据源配置类DataSourceConfig

@Configuration
@MapperScan("com.ebt.demo.mapper") //对应mapper接口所在包扫描
public class DataSourceConfig {
	/**
     * mybatisPlus分页配置
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        return paginationInterceptor;
    }

	/**
     * 主数据源
     */
    @Bean
    @ConfigurationProperties("spring.datasource.druid.master")
    public DataSource masterDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

	/**
     * 从数据源
     */
    @Bean
    @ConfigurationProperties("spring.datasource.druid.slave")
    public DataSource slaveDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * 动态数据源配置
     */
    @Bean
    public DataSource myRoutingDataSource(@Qualifier("masterDataSource") DataSource masterDataSource,
                                          @Qualifier("slaveDataSource") DataSource slaveDataSource) {
        Map<Object, Object> targetDataSource = new HashMap<>();
        targetDataSource.put(DBTypeEnum.MASTER, masterDataSource);
        targetDataSource.put(DBTypeEnum.SLAVE, slaveDataSource);
        MyRoutingDataSource myRoutingDataSource = new MyRoutingDataSource();
        //找不到用默认数据源
        myRoutingDataSource.setDefaultTargetDataSource(masterDataSource);
        //可选择目标数据源
        myRoutingDataSource.setTargetDataSources(targetDataSource);
        return myRoutingDataSource;
    }

    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(myRoutingDataSource(masterDataSource(),slaveDataSource()));
        //mapper下xml文件位置
        sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*.xml"));

        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setCacheEnabled(false);
        sqlSessionFactory.setConfiguration(configuration);
        sqlSessionFactory.setGlobalConfig(globalConfig());
        return sqlSessionFactory.getObject();
    }

    /**
     * mybatisPlus自定义配置
     */
    public GlobalConfig globalConfig(){
        GlobalConfig globalConfig = new GlobalConfig();
        GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig();
        dbConfig.setIdType(IdType.AUTO);
        globalConfig.setDbConfig(dbConfig);
        return globalConfig;
    }
}

5.自定义注解,在service上可以指定方法调用master或slave

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
    DBTypeEnum value() default DBTypeEnum.MASTER;
}

6.切面儿AOP配置(这一步很关键)

对于MybatisPlus在Service层已经实现的方法(get*、list*、page*、count*、select*、query*、save*、update*、remove*、delete*),就直接在切面这边定义“读”或者“写”,切换对应的数据源。而对于其他的方法,则需要加上@DataSource的注解来区分。

@Aspect
@Order(-1)
@Component
public class DataSourceAop {
    @Pointcut("(execution(* com.test.service..*.get*(..)) " +
            "|| execution(* com.test.service..*.list*(..)) " +
            "|| execution(* com.test.service..*.page*(..)) " +
            "|| execution(* com.test.service..*.count*(..)) " +
            "|| execution(* com.test.service..*.select*(..)) " +
            "|| execution(* com.test.service..*.query*(..)))")
    public void readPointcut() {
    }

    @Pointcut("execution(* com.test.service..*.save*(..)) " +
            "|| execution(* com.test.service..*.update*(..)) " +
            "|| execution(* com.test.service..*.remove*(..)) " +
            "|| execution(* com.test.service..*.delete*(..)) ")
    public void writePointcut() {
    }

    @Pointcut("@within(com.test.util.DataSource) " +
            "|| @annotation(com.test.util.DataSource)")
    public void pointcut(){
    }

    @Before("readPointcut()")
    public void read() {
        DBContextHolder.slave();
    }

    @Before("writePointcut()")
    public void write() {
        DBContextHolder.master();
    }

    @Before("pointcut() && @annotation(dataSource)")
    public void doBefore(DataSource dataSource){
        String value = dataSource.value().getValue();
        if (value.equals(DBTypeEnum.MASTER.getValue())) {
            DBContextHolder.master();
        }
        if (value.equals(DBTypeEnum.SLAVE.getValue())) {
            DBContextHolder.slave();
        }

    }

    @After("readPointcut()")
    public void cleanRead() {
        DBContextHolder.cleanAll();
    }

    @After("writePointcut()")
    public void cleanWrite() {
        DBContextHolder.cleanAll();
    }

    @After("pointcut()")
    public void clean() {
        DBContextHolder.cleanAll();
    }
}

至此,我们已经全部整合完毕了,接下来就可以测试了!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
对于Spring BootMyBatis Plus多数据源配置MySQL和PostgreSQL,你可以按照以下步骤进行操作: 1. 首先,在你的Spring Boot项目中添加MySQL和PostgreSQL的依赖。在`pom.xml`文件中添加以下依赖: ```xml <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> </dependency> ``` 2. 接下来,配置数据源。在`application.properties`或`application.yml`文件中添加以下配置: ```yaml # MySQL 数据源配置 spring.datasource.mysql.url=jdbc:mysql://localhost:3306/mysql_db spring.datasource.mysql.username=root spring.datasource.mysql.password=123456 # PostgreSQL 数据源配置 spring.datasource.postgresql.url=jdbc:postgresql://localhost:5432/postgresql_db spring.datasource.postgresql.username=postgres spring.datasource.postgresql.password=123456 ``` 3. 然后,创建数据源配置类。创建两个数据源的配置类,分别用于MySQL和PostgreSQL。例如,创建名为`MySQLDataSourceConfig`和`PostgreSQLDataSourceConfig`的类,并分别添加`@Configuration`和`@ConfigurationProperties`注解。 ```java @Configuration @ConfigurationProperties(prefix = "spring.datasource.mysql") public class MySQLDataSourceConfig { private String url; private String username; private String password; // 省略 getter 和 setter 方法 } ``` ```java @Configuration @ConfigurationProperties(prefix = "spring.datasource.postgresql") public class PostgreSQLDataSourceConfig { private String url; private String username; private String password; // 省略 getter 和 setter 方法 } ``` 4. 接下来,配置数据源。在`DataSourceConfig`类中,创建两个数据源的`DataSource`实例,并将它们注入到`SqlSessionFactory`中。 ```java @Configuration public class DataSourceConfig { @Bean(name = "mysqlDataSource") @ConfigurationProperties(prefix = "spring.datasource.mysql") public DataSource mysqlDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "postgresqlDataSource") @ConfigurationProperties(prefix = "spring.datasource.postgresql") public DataSource postgresqlDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "sqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("mysqlDataSource") DataSource mysqlDataSource, @Qualifier("postgresqlDataSource") DataSource postgresqlDataSource) throws Exception { SqlSessionFactoryBean sessionFactory

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值