spring boot + mybatis plus 动态数据源实现

spring boot + mybatis plus 动态数据源实现

参考官网文档

https://mp.baomidou.com/guide/dynamic-datasource.html#%E6%96%87%E6%A1%A3-documentation

pom引入依赖

<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.1.1</version>
        </dependency>
          <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis.plus.version}</version>
        </dependency>

配置文件配置

spring:
  # 数据源 配置
  datasource:
    dynamic:
      primary: order #设置默认的数据源或者数据源组,默认值即为master
      strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候会抛出异常,不启动则使用默认数据源.
      datasource:
        order: # youpin
          url: jdbc:mysql://127.0.0.1:3306/order?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&serverTimezone=GMT%2B8
          username: bizuser
          password: biz*2019
          driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
        user:
          url: jdbc:mysql://127.0.0.1:3306/user?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
          username: bizuser
          password: biz*2019
          driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置

service 增加注解

@DS 默认数据源可以不加次注解

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lujia
 * @since 2021-03-19
 */
@DS("user")
@Service
@Slf4j
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements IMemberService {
    
}

整合druid数据源

  • 引入依赖
  <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.17</version>
        </dependency>
  • 配置文件修改
spring:
  # 数据源 配置
  datasource:
    dynamic:
      primary: order #设置默认的数据源或者数据源组,默认值即为master
      strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候会抛出异常,不启动则使用默认数据源.
       druid:
        initial-size: 5
        min-idle: 5
        maxActive: 16
        maxWait: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: SELECT 1
        filters: stat
      datasource:
        order: # youpin
          url: jdbc:mysql://127.0.0.1:3306/order?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&serverTimezone=GMT%2B8
          username: bizuser
          password: biz*2019
          driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
        user:
          url: jdbc:mysql://127.0.0.1:3306/user?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
          username: bizuser
          password: biz*2019
          driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置

  • 排除durid 默认的数据源配置类
@SpringBootApplication(exclude = DruidDataSourceAutoConfigure.class)

读写分离

  • 增加自定义mybatis配置

    /**
     * @author lujia
     */
    @Configuration
    public class MybatisPlusConfig {
    
        /**
         * 分页插件
         */
        @Bean
        public PaginationInterceptor paginationInterceptor() {
            PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
            paginationInterceptor.setLimit(-1);
            return paginationInterceptor;
        }
    
    
        @Bean
        public MasterSlaveAutoRoutingPlugin masterSlaveAutoRoutingPlugin(){
            return new MasterSlaveAutoRoutingPlugin();
        }
    
    }
    
  • MasterSlaveAutoRoutingPlugin 是mybatis plus自带的插件,我们可以自定义实现,注入自定义的bean,实现读写的数据源路由

    /**
     * Copyright © 2018 organization baomidou
     * <pre>
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     * <pre/>
     */
    package com.baomidou.dynamic.datasource.plugin;
    
    import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
    import com.baomidou.dynamic.datasource.support.DbHealthIndicator;
    import com.baomidou.dynamic.datasource.support.DdConstants;
    import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.ibatis.executor.Executor;
    import org.apache.ibatis.mapping.MappedStatement;
    import org.apache.ibatis.mapping.SqlCommandType;
    import org.apache.ibatis.plugin.*;
    import org.apache.ibatis.session.ResultHandler;
    import org.apache.ibatis.session.RowBounds;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.util.StringUtils;
    
    import java.util.Properties;
    
    /**
     * Master-slave Separation Plugin with mybatis
     *
     * @author TaoYu
     * @since 2.5.1
     */
    @Intercepts({
            @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
            @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
    @Slf4j
    public class MasterSlaveAutoRoutingPlugin implements Interceptor {
    
        @Autowired
        private DynamicDataSourceProperties properties;
    
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            Object[] args = invocation.getArgs();
            MappedStatement ms = (MappedStatement) args[0];
            boolean empty = true;
            try {
                empty = StringUtils.isEmpty(DynamicDataSourceContextHolder.peek());
                if (empty) {
                    DynamicDataSourceContextHolder.push(getDataSource(ms));
                }
                return invocation.proceed();
            } finally {
                if (empty) {
                    DynamicDataSourceContextHolder.clear();
                }
            }
        }
    
        /**
         * 获取动态数据源名称,重写注入 DbHealthIndicator 支持数据源健康状况判断选择
         *
         * @param mappedStatement mybatis MappedStatement
         * @return 获取真实的数据源名称
         */
        public String getDataSource(MappedStatement mappedStatement) {
            String slave = DdConstants.SLAVE;
            if (properties.isHealth()) {
                /*
                 * 根据从库健康状况,判断是否切到主库
                 */
                boolean health = DbHealthIndicator.getDbHealth(DdConstants.SLAVE);
                if (!health) {
                    health = DbHealthIndicator.getDbHealth(DdConstants.MASTER);
                    if (health) {
                        slave = DdConstants.MASTER;
                    }
                }
            }
            return SqlCommandType.SELECT == mappedStatement.getSqlCommandType() ? slave : DdConstants.MASTER;
        }
    
        @Override
        public Object plugin(Object target) {
            return target instanceof Executor ? Plugin.wrap(target, this) : target;
        }
    
        @Override
        public void setProperties(Properties properties) {
        }
    }
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值