springboot 2.0 整合druid+ mybatisPlus 动态多数据源

springboot这个框架,相信现在大部分企业都是使用的该框架,但是2.0 之后与之前的版本还是有些区别。这里我们谈谈如何整合mybatisPlus多数据源

一 、首先父模块pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.silankeji</groupId>
    <artifactId>framework</artifactId>
    <version>1.0-RELEASE</version>
    <packaging>pom</packaging>
    <name>framework</name>
    <url>www.silankeji.cn</url>

    <modules>
        <module>mybaitsplus</module>
        <module>swagger</module>
        <module>redis</module>
        <module>commons</module>
    </modules>

    <properties>
        <spring.boot.version>2.1.1.RELEASE</spring.boot.version>
        <spring.version>5.1.3.RELEASE</spring.version>
        <mysql.version>8.0.13</mysql.version>
        <fastJson.version>1.2.47</fastJson.version>
        <common.version>2.6</common.version>
        <mybatis.version>2.3</mybatis.version>
        <druid.version>1.1.10</druid.version>
        <devtool.version>2.0.3.RELEASE</devtool.version>
        <common.lang3.version>3.8.1</common.lang3.version>
        <maven.compiler.version>3.8.0</maven.compiler.version>
        <swagger2.version>2.9.2</swagger2.version>
        <jedis.version>2.9.0</jedis.version>
    </properties>
    <!-- 版本控制 只是声明而不加载jar包-->
    <dependencyManagement>
        <dependencies>
            <!--这里maven只是单继承所以用scope import 来继承spring根包进行统一版本声明-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--各个子模块版本声明-->
            <dependency>
                <groupId>com.silankeji</groupId>
                <artifactId>mybaitsplus</artifactId>
                <version>${project.version}</version>
            </dependency>
            <!--swagger-->
            <dependency>
                <groupId>com.silankeji</groupId>
                <artifactId>swagger</artifactId>
                <version>${project.version}</version>
            </dependency>
            <!--redis-->
            <dependency>
                <groupId>com.silankeji</groupId>
                <artifactId>redis</artifactId>
                <version>${project.version}</version>
            </dependency>
            <!--common 比如一些工具类一些异常类一些枚举等-->
            <dependency>
                <groupId>com.silankeji</groupId>
                <artifactId>commons</artifactId>
                <version>${project.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!--公共jar包-->
    <dependencies>
        <!--fastJson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastJson.version}</version>
        </dependency>
        <!--############################common模块包#################-->
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>${common.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${common.lang3.version}</version>
        </dependency>
        <!-- ############################ springboot模块包 ###################-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--自动配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        <!--aop-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!--logger日志-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>
        <!--热启动-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version>${devtool.version}</version>
            <scope>runtime</scope>
        </dependency>
        <!--测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <!--解决properties路径找不错错误-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>
        <!-- ##########################spring模块包############################-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
    </dependencies>

    <!--发布到maven私服-->
    <distributionManagement>
        <repository>
            <id>releases</id>
            <url>http://自己的maven私服/repository/maven-releases</url>
        </repository>
        <snapshotRepository>
            <id>snapshots</id>
            <url>http://自己的maven私服/repository/maven-snapshots</url>
        </snapshotRepository>
    </distributionManagement>

    <build>
        <plugins>
            <!--编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.version}</version>
                <configuration>
                    <target>1.8</target>
                    <source>1.8</source>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>


</project>

二、mybatis模块 pom.xml引入依赖jar包

这里我是父模块管理jar包版本,此处可以自己引用相关版本

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>framework</artifactId>
        <groupId>com.silankeji</groupId>
        <version>1.0-RELEASE</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>mybaitsplus</artifactId>
    <packaging>jar</packaging>
    <name>mybatisplus</name>
    <url>http://maven.apache.org</url>

    <dependencies>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        <!--jdbc -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!--mybatisPlus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId> mybatis-plus-boot-starter</artifactId>
            <version>${mybatis.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-jdbc</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-autoconfigure</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <!--commons包-->
        <dependency>
            <groupId>com.silankeji</groupId>
            <artifactId>commons</artifactId>
            <version>1.0-RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.version}</version>
                <configuration>
                    <target>1.8</target>
                    <source>1.8</source>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

三、定义DataSource 注解

自定义多数据源切换的注解,默认为主库

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {

    String value() default "master";
}

四、配置文件

这里需要配置druid以及mybatisplus的config配置文件
MybatisPlusConfig.java

@Configuration("mybatisPlusConfig")
@MapperScan(basePackages = "com.silankeji.**.mapper", sqlSessionTemplateRef = "sqlSessionTemplate")
public class MybatisPlusConfig {

    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        //开启PageHelper
        paginationInterceptor.setLocalPage(true);
        return paginationInterceptor;
    }

    /**
     * sql执行效率插件
     * 只在dev和test环境生效
     */
    @Bean
    @Profile({"dev", "test"})
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        //sql执行的最大时间1秒
        performanceInterceptor.setMaxTime(1000);
        //是否格式化
        performanceInterceptor.setFormat(true);
        return performanceInterceptor;
    }

    @Bean("master")
    @ConfigurationProperties(prefix = "spring.datasource.druid.master")
    @Primary
    public DataSource master() {
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * 动态数据源
     */
    @Bean(name = "dynamic")
    public DataSource multipleDataSource(@Qualifier("master") DataSource master) {
        //设置默认数据源
        DynamicDataSource.getInstance().setDefaultTargetDataSource(master);
        DataSourceMap.getDataSourceMap().put("master", master);
        DynamicDataSource.getInstance().setTargetDataSources(DataSourceMap.getDataSourceMap());
        return DynamicDataSource.getInstance();
    }

    @Bean(name = "transactionManager")
    @Order
    public DataSourceTransactionManager transactionManager(@Qualifier("dynamic") DataSource dataSource) {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        //这里进行动态数据源重新设置
        DynamicDataSource.getInstance().setTargetDataSources(DataSourceMap.getDataSourceMap());
        //注入resolvedDataSources中
        DynamicDataSource.getInstance().afterPropertiesSet();
        return transactionManager;
    }

    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamic") DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(dataSource);
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setCacheEnabled(false);
        sqlSessionFactory.setConfiguration(configuration);
        sqlSessionFactory.setPlugins(new Interceptor[]{
                //添加分页功能
                paginationInterceptor()
        });
        return sqlSessionFactory.getObject();
    }

    @Bean(name = "sqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier(value = "sqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory);
        return sqlSessionTemplate;
    }

}

DruidConfig.java
这里设置了默认用户以及密码可以取消

@Configuration
@ConditionalOnProperty(name = "druid.config.enable",havingValue = "true")
public class DruidConfig{

    @Resource
    private Environment environment;

    private final Map<String, String> paramMap = new HashMap<>(7);

    @Bean
    public ServletRegistrationBean startViewServlet() {
        getDruidConfigProperties();
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        //Ip白名单,多个在value中用逗号隔开,不配置默认所有
        servletRegistrationBean.addInitParameter("allow", paramMap.get("allow"));
        //ip 黑名单,这里黑名单优先级大于白名单
        servletRegistrationBean.addInitParameter("deny", paramMap.get("deny"));
        //控制台管理
        servletRegistrationBean.addInitParameter("loginUsername", paramMap.get("loginUsername"));
        servletRegistrationBean.addInitParameter("loginPassword", paramMap.get("loginPassword"));
        //是否可以点击页面的重置按钮
        servletRegistrationBean.addInitParameter("resetEnable", paramMap.get("resetEnable"));
        return servletRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean statFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        //添加过滤规则
        filterRegistrationBean.addUrlPatterns(paramMap.get("urlPatterns"));
        //忽略过滤的格式
        filterRegistrationBean.addInitParameter("exclusions", paramMap.get("exclusions"));
        return filterRegistrationBean;
    }

    private void getDruidConfigProperties(){
        if(StringUtils.isEmpty(environment.getProperty("druid.config.allow"))){
            paramMap.put("allow","");
        }else{
            paramMap.put("allow",environment.getProperty("druid.config.allow"));
        }

        if(StringUtils.isEmpty(environment.getProperty("druid.config.deny"))){
            paramMap.put("deny","");
        }else{
            paramMap.put("deny",environment.getProperty("druid.config.deny"));
        }

        if(StringUtils.isEmpty(environment.getProperty("druid.config.loginUsername"))){
            paramMap.put("loginUsername","admin");
        }else{
            paramMap.put("loginUsername",environment.getProperty("druid.config.loginUsername"));
        }

        if(StringUtils.isEmpty(environment.getProperty("druid.config.loginPassword"))){
            paramMap.put("loginPassword","admin123");
        }else{
            paramMap.put("loginPassword",environment.getProperty("druid.config.loginPassword"));
        }

        if(StringUtils.isEmpty(environment.getProperty("druid.config.resetEnable"))){
            paramMap.put("resetEnable","false");
        }else{
            paramMap.put("resetEnable",environment.getProperty("druid.config.resetEnable"));
        }

        if(StringUtils.isEmpty(environment.getProperty("druid.config.urlPatterns"))){
            paramMap.put("urlPatterns","/*");
        }else{
            paramMap.put("urlPatterns",environment.getProperty("druid.config.urlPatterns"));
        }

        if(StringUtils.isEmpty(environment.getProperty("druid.config.exclusions"))){
            paramMap.put("exclusions","*.js,*.gif,*.jpg,*.png ,*.css,*.ico,/druid/*");
        }else{
            paramMap.put("exclusions",environment.getProperty("druid.config.exclusions"));
        }
    }

}

配置动态多数据源路由对象
DynamicDataSource.java

public class DynamicDataSource extends AbstractRoutingDataSource {

    private static volatile DynamicDataSource dynamicDataSource;

    private DynamicDataSource(){}



    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDatasource();
    }

    /**
     * 单例获取对象
     * @return DynamicDataSource
     */
    public static DynamicDataSource getInstance() {
        if (dynamicDataSource == null) {
            synchronized (DynamicDataSource.class) {
                if (dynamicDataSource == null) {
                    dynamicDataSource = new DynamicDataSource();
                }
            }
        }
        return dynamicDataSource;
    }

}

配置多数据源上下文
DataSourceContextHolder.java

public class DataSourceContextHolder {

    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<String>();

    public static void setDataSource(String name){
        CONTEXT_HOLDER.set(name);
    }

    public static String getDatasource(){
        return CONTEXT_HOLDER.get();
    }

    public static void cleanDataSource(){
        CONTEXT_HOLDER.remove();
    }
}

配置数据源存储容器
DataSourceMap.java

 public final class DataSourceMap {

    /**
     * 全局静态存放数据源名称Map
     */
    private static final Map<Object,Object> DATASOURCEMAP = new HashMap<>();


    private DataSourceMap(){
    }

    /**
     * 获取数据源集合
     * @return
     */
    public static Map<Object,Object> getDataSourceMap(){
        return DATASOURCEMAP;
    }

    /**
     * 添加数据源bean进入集合中
     * @param dataSourceBeanName
     * @return
     */
    public static boolean setDataSourceBeanName(String dataSourceBeanName, DataSource dataSource){
        if(StringUtils.isBlank(dataSourceBeanName)||dataSource == null){
            return false;
        }
       return DATASOURCEMAP.put(dataSourceBeanName,dataSource)!=null;

    }

    /**
     * 删除集合中的某个数据源
     * @param dataSourceBeanName
     * @return
     */
    public static boolean remove(String dataSourceBeanName){
        if(StringUtils.isBlank(dataSourceBeanName)){
            return false;
        }
        return DATASOURCEMAP.remove(dataSourceBeanName)==null;
    }

}

五、数据源动态切面设置

切记要优先加载
DataSourceAspect.java

@Component
@Aspect
@Order(-1)
public class DataSourceAspect {

    private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceAspect.class);

    @Pointcut("@within(com.silankeji.mybatisplus.annotations.DataSource) || @annotation(com.silankeji.mybatisplus.annotations.DataSource)")
    public void pointCut(){

    }

    @Before("pointCut() && @annotation(dataSource)")
    public void doBefore(DataSource dataSource){
        LOGGER.info("选择数据源---"+dataSource.value());
        DataSourceContextHolder.setDataSource(dataSource.value());
    }

    @After("pointCut()")
    public void doAfter(){
        DataSourceContextHolder.cleanDataSource();
    }
}

六、客户端的使用

1.引入jar包

<dependency>
            <groupId>com.silankeji</groupId>
            <artifactId>mybaitsplus</artifactId>
            <version>1.0-RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.silankeji</groupId>
            <artifactId>swagger</artifactId>
            <version>1.0-RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.silankeji</groupId>
            <artifactId>commons</artifactId>
            <version>1.0-RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.silankeji</groupId>
            <artifactId>redis</artifactId>
            <version>1.0-RELEASE</version>
        </dependency>

2.属性配置

#mybatisPlus 配置
mybatis-plus:
  #xml 路径
  mapper-locations: classpath*:mybatis/*.xml
  global-config:
  # 全局编码
    id-type: 3
    #逻辑删除
    logic-delete-value: 1
    #逻辑不删除
    logic-not-delete-value: 0
    #对应数据库字段下划线转java驼峰命名
    db-column-underline: true
  configuration:
    # map 键值转驼峰
    map-underscore-to-camel-case: true
#swagger2配置
swagger2:
  enable: true
  title: frameDemo
  basePack: com.silankeji.demo2.controller

#druid 配置
spring:
  redis:
    enable: true
  datasource:
    druid:
      #开启com.silankeji.mybatisplus 数据源配置信息
      enable: true
      master:
        #数据源配置 wall表示防火墙
        filters: stat,wall,log4j2
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://数据库地址:3306/master?useUnicode=true&characterEncoding=UTF-8&allowMutiqueries=true
        username: root
        password: root123
        #初始线程数,最小活跃线程,最大活跃线程
        initial-size: 1
        min-idle: 1
        max-active: 5
        # 连接等待时间单位毫秒
        max-wait: 60000
        #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
        time-between-eviction-runs-millis: 60000
        #配置一个连接在池中最小生存的时间,单位是毫秒
        min-evictable-idle-time-millis: 300000
        validation-query: SELECT 1 FROM DUAL
        #\u6307\u660E\u8FDE\u63A5\u662F\u5426\u88AB\u7A7A\u95F2\u8FDE\u63A5\u56DE\u6536\u5668\uFF0C\u8FDB\u884C\u6821\u9A8C\uFF0C\u6821\u9A8C\u5931\u8D25\u5219\uFF0C\u6B64\u8FDE\u63A5\u4ECE\u6C60\u4E2D\u5220\u9664
        test-while-idle: true
        #\u501F\u51FA\u8FDE\u63A5\u65E0\u9700\u6D4B\u8BD5
        test-on-borrow: false
        test-on-return: false
        #打开PSCache,并且指定每个连接上PSCache的大小
        pool-prepared-statements: false
        #\u4E0Eoracle\u6570\u636E\u5E93\u6709\u5173
        max-pool-prepared-statement-per-connection-size: 20
        #\u6253\u5F00mergeSql\u529F\u80FD\uFF0C\u6162Sql\u8BB0\u5F55
        connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      slaver:
        #\u914D\u7F6E\u76D1\u63A7\u7EDF\u8BA1\u62E6\u622A\u7684filters\uFF0Cwall\u7528\u4E8E\u9632\u706B\u5899
        filters: stat,wall,log4j2
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://数据库地址:3306/slaver?useUnicode=true&characterEncoding=UTF-8&allowMutiqueries=true
        username: root
        password: root123
        #\u521D\u59CB\u5316\u5927\u5C0F\uFF0C\u6700\u5C0F\u8FDE\u63A5\uFF0C\u6700\u5927\u8FDE\u63A5
        initial-size: 1
        min-idle: 1
        max-active: 5
        #\u83B7\u53D6\u8FDE\u63A5\u7B49\u5F85\u8D85\u65F6\u65F6\u95F4
        max-wait: 60000
        #\u914D\u7F6E\u95F4\u9694\u591A\u4E45\u8FDB\u884C\u4E00\u6B21\u68C0\u67E5\uFF0C\u9700\u8981\u5173\u95ED\u7684\u7A7A\u95F2\u8FDE\u63A5
        time-between-eviction-runs-millis: 60000
        #\u914D\u7F6E\u4E00\u4E2A\u8FDE\u63A5\u5728\u6C60\u4E2D\u7684\u6700\u5C0F\u751F\u5B58\u65F6\u95F4
        min-evictable-idle-time-millis: 300000
        validation-query: SELECT 1 FROM DUAL
        #\u6307\u660E\u8FDE\u63A5\u662F\u5426\u88AB\u7A7A\u95F2\u8FDE\u63A5\u56DE\u6536\u5668\uFF0C\u8FDB\u884C\u6821\u9A8C\uFF0C\u6821\u9A8C\u5931\u8D25\u5219\uFF0C\u6B64\u8FDE\u63A5\u4ECE\u6C60\u4E2D\u5220\u9664
        test-while-idle: true
        #\u501F\u51FA\u8FDE\u63A5\u65E0\u9700\u6D4B\u8BD5
        test-on-borrow: false
        test-on-return: false
        #\u6253\u5F00psCache \u5E76\u6307\u5B9A\u6BCF\u4E2ApsCache\u5927\u5C0F\uFF0Coracle\u4E3Atrue mysql\u4E3Afalse\uFF0C\u5206\u5E93\u5206\u8868\u8F83\u591A\u8BBE\u7F6Efalse
        pool-prepared-statements: false
        #\u4E0Eoracle\u6570\u636E\u5E93\u6709\u5173
        max-pool-prepared-statement-per-connection-size: 20
         #通过connectProperties属性来打开mergeSql功能;慢SQL记录
        connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      slaver1:
        #数据源配置 wall表示防火墙
        filters: stat,wall,log4j2
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://数据库地址:3306/slaver1?useUnicode=true&characterEncoding=UTF-8&allowMutiqueries=true
        username: root
        password: root123
        #初始线程数,最小活跃线程,最大活跃线程
        initial-size: 1
        min-idle: 1
        max-active: 5
        # 连接等待时间单位毫秒
        max-wait: 60000
        #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
        time-between-eviction-runs-millis: 60000
        #配置一个连接在池中最小生存的时间,单位是毫秒
        min-evictable-idle-time-millis: 300000
        validation-query: SELECT 1 FROM DUAL
        #\u6307\u660E\u8FDE\u63A5\u662F\u5426\u88AB\u7A7A\u95F2\u8FDE\u63A5\u56DE\u6536\u5668\uFF0C\u8FDB\u884C\u6821\u9A8C\uFF0C\u6821\u9A8C\u5931\u8D25\u5219\uFF0C\u6B64\u8FDE\u63A5\u4ECE\u6C60\u4E2D\u5220\u9664
        test-while-idle: true
        #\u501F\u51FA\u8FDE\u63A5\u65E0\u9700\u6D4B\u8BD5
        test-on-borrow: false
        test-on-return: false
        #打开PSCache,并且指定每个连接上PSCache的大小
        pool-prepared-statements: false
        #\u4E0Eoracle\u6570\u636E\u5E93\u6709\u5173
        max-pool-prepared-statement-per-connection-size: 20
        #\u6253\u5F00mergeSql\u529F\u80FD\uFF0C\u6162Sql\u8BB0\u5F55
        connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
#druid页面配置
druid:
  config:
    #是否开启druid监控com.silankeji.mybatisplus
    enable: true
    #白名单 默认所有可访问
    allow: 127.0.0.1
    #黑名单 默认为空
    deny: 118.25.23.12
    #账号 默认admin
    loginUsername: root
    #密码 默认admin123
    loginPassword: root123
    #是否允许点击页面的重置按钮,默认false
    resetEnable: false
    #过滤url 默认 /*
    urlPatterns: /*
    #不过滤的资源,注意*打头必须加双引号,下面值为默认值
    exclusions: "*.js,*.gif,*.jpg,*.png ,*.css,*.ico,/druid/*"
  1. 动态数据源配置
    MultiDataSource.java
@Configuration
public class MultiDataSource{

    @Bean("slaver")
    @ConfigurationProperties(prefix = "spring.datasource.druid.slaver")
    public DataSource slaver() {
        //创建数据源
        DataSource dataSource = DruidDataSourceBuilder.create().build();
        //将数据源放入动态池
        DataSourceMap.setDataSourceBeanName("slaver",dataSource);
       return dataSource;
    }

    @Bean("zzz")
    @ConfigurationProperties(prefix = "spring.datasource.druid.slaver1")
    public DataSource slaver1() {
        //创建数据源
        DataSource dataSource = DruidDataSourceBuilder.create().build();
        //将数据源放入动态池
        DataSourceMap.setDataSourceBeanName("zzz",dataSource);
        return dataSource;
    }
}

4.代码中使用,这里有3个数据源只需要使用注解@DataSource就可以使用不同的数据源

@RestController
@Api(value = "操作员工相关相信Controller")
public class EmployeeController {

    private static final Logger LOG = LoggerFactory.getLogger(EmployeeController.class);

    @Resource
    private EmployeeService employeeService;

    @RequestMapping(value = "/queryEmployee/{empNo}",method=RequestMethod.POST)
    @ApiOperation(value = "获取员工信息",notes = "根据员工编号查询员工相关信息",httpMethod = "POST",produces = "application/json")
    @ApiImplicitParam(name = "empNo",value = "员工编号如:1,2...",required = true,dataType="string",paramType = "path")
    @DataSource
    public BaseResponse getEmployeeInfo(@PathVariable(name = "empNo") String employeeNumber){
        LOG.info("begin query employee info by employeeNumber:{}",employeeNumber);
        EntityWrapper<Employee> wrapper = new EntityWrapper<>();
        wrapper.eq("employeeNumber",employeeNumber);
        BaseResponse response = new BaseResponse();
        response.setResult(employeeService.selectOne(wrapper));
        LOG.info("query employee info is{}",JSON.toJSONString(response));
        return response;
    }

    @RequestMapping(value = "/addEmployee",method = RequestMethod.POST)
    @ApiOperation(value = "添加员工信息",notes ="增加员工相关信息",httpMethod = "POST",produces = "application/json",consumes = "application/json")
    @DataSource("zzz")
    public BaseResponse addEmployeeInfo(@RequestBody @ApiParam(name = "employee",value = "员工信息类") Employee employee){
        LOG.info("begin add employee info:{}",JSON.toJSONString(employee));
        BaseResponse response = new BaseResponse();
        response.setResult(employeeService.insert(employee));
        LOG.info("add employee info is {}",JSON.toJSONString(response));
        return response;
    }

    @RequestMapping(value = "/modifyEmployee",method = RequestMethod.POST)
    @ApiOperation(value = "修改员工信息",notes ="编辑员工相关信息",httpMethod = "POST",produces = "application/json",consumes = "application/json")
    @DataSource("slaver")
    public BaseResponse modifyEmployeeInfo(@RequestBody @ApiParam(name = "employee",value = "员工信息类") Employee employee){
        LOG.info("begin update employee info:{}",JSON.toJSONString(employee));
        BaseResponse response = new BaseResponse();
        response.setResult(employeeService.update(employee,new EntityWrapper<Employee>().eq("employeeNumber",employee.getEmployeeNumber())));
        LOG.info("update employee info is {}",JSON.toJSONString(response));
        return response;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容