SpringBoot多数据源方案

        近来公司制定了未来一年的的大方向,博主负责的当前的项目还是多年前的springcloud那套架构,而其他项目组都还是单体项目或者是更新的架构,各种架构层出不穷,数据和接口,业务打通比较困难,为了短时间内迅速的进行开发,博主亲自操刀整合了个单体项目,采用的是springboot+mybatisplus+shiro+redis+swagger+多数据源的方案,之前博主最先想采用satoken的权限框架的,后来问了下团队其它成员不会使用,为了尽快开发,还是选用的是shiro的权限框架,姜还是老的辣嘛,本期重点来了,由于业务需要接入多个数据源,所以采坑实现多数据源方案,博主之前还没仔细研究过这个多数据源的方案,踩坑几天,总结了一下,文笔有限,看看就好,如有不对,还请指出。

        目前实现的多数据源的方案有两种:

 先前讲下springboot注入数据源的目前有两种数据库连接池,

第一种是:


            com.alibaba
            druid
            1.2.6
        

第二种:


    com.alibaba
    druid-spring-boot-starter
    1.1.22

大概的区别就是,两者其实包含关系,第二种对第一种做了整合,第一种方式还得写注入datasource的一些getset方法,第二种就不用写了,直接就可以让spring自动扫描读配置文件的信息,建议还是用第二种,简单方便。

接下来进入正题,多数据源的方案:

第一种:使用分包方式,不同的数据源配置不同的MapperScan和mapper文件;

第二种:使用APO切片方式,实现动态数据源切换;

第三种:使用多数据源的框架:dynamic-datasource-spring-boot-starter,前提是用的是mubatisplus;

三种方式的区别:

(1)、分包方式可以使用Transactional API实现分布式事务。

(2)、AOP动态配置数据源方式缺点在于无法实现全局分布式事务。

(3)、dynamic框架比较灵活,可以实现事务隔离和注解的形式,简单高效,就是受限于mybatisplus框架。

相比之下,博主也是采坑几天,所有的方式都实现了一遍。贴上不同方式的实现过程如下:

一:分包方式:

POM:

        


            com.baomidou
            mybatis-plus-boot-starter
            3.4.2
        

        
            com.baomidou
            mybatis-plus-generator
            3.4.1
        


        
            com.alibaba
            druid-spring-boot-starter
            1.2.6
        

        
            ru.yandex.clickhouse
            clickhouse-jdbc
            0.3.0
        


            mysql
            mysql-connector-java
            runtime
        
 
            org.springframework.boot
            spring-boot-starter-aop
        

yml:

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      master:
        url: jdbc:mysql://localhost:3306/reddata?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=true&serverTimezone=UTC
        username: root
        password: root
        driver-class-name: com.mysql.cj.jdbc.Driver
    click:
      url: jdbc:clickhouse://
      driverClassName: ru.yandex.clickhouse.ClickHouseDriver
      initialSize: 10
      maxActive: 100
      minIdle: 10
      maxWait: 6000
    testOnBorrow: true
    validationQuery: SELECT 1

目录结构:

SpringBoot多数据源方案_第1张图片

 SpringBoot多数据源方案_第2张图片

核心config类:

package cn.reddata.plus.www.config;


import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * MybatisConfig配置类
 *
 * @author aries
 * @date 2021/12/03 0:31
 */
@Configuration
@ConditionalOnClass(value = {PaginationInterceptor.class})
@MapperScan("cn.reddata.plus.www.domain.mapper.mysql")
@MapperScan("cn.reddata.plus.www.domain.mapper.click")
public class MybatisPlusConfig {

    //设置分页的bean=====================================================================================================
    @Bean
    public PaginationInterceptor mysqlPaginationInterceptor() {

        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setDbType(DbType.MYSQL);
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }

    @Bean
    public PaginationInterceptor clickPaginationInterceptor() {

        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setDbType(DbType.CLICK_HOUSE);
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }

//    @Bean(name = "db1")
//    @ConditionalOnProperty(name = "spring.datasource.druid.enabled",havingValue = "true")
//    @ConfigurationProperties(prefix = "spring.datasource.druid.master" )
//    public DataSource db1() {
//        return DruidDataSourceBuilder.create().build();
//    }

    /**
     * 创建数据源
     */
    @Bean(name = "db1")
    @ConfigurationProperties(prefix = "spring.datasource.druid.master")
    public DataSource db1() {
        return new DruidDataSource();
    }


    /**
     * 创建数据源
     */
    @Bean(name = "db2")
    @ConfigurationProperties(prefix = "spring.datasource.click")
    public DataSource db2() {
        return new DruidDataSource();
    }

    @Configuration
    @MapperScan(basePackages = "cn.reddata.plus.www.domain.mapper.mysql", sqlSessionTemplateRef = "sqlSessionTemplate")
    public class Db1 {
        @Bean
        @Primary
        public SqlSessionFactory sqlSessionFactory(@Qualifier("db1") DataSource dataSource) throws Exception {
            //mybatis应该使用  SqlSessionFactoryBean
            //SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();

            //mybatis-plus应该使用  MybatisSqlSessionFactoryBean  否则无法使用baseMapper
            MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
            sqlSessionFactory.setDataSource(dataSource);
            sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                    .getResources("classpath*:/mappers/mysql/*.xml"));
            //添加分页功能================================================================================================
            sqlSessionFactory.setPlugins(new Interceptor[]{mysqlPaginationInterceptor()});
            return sqlSessionFactory.getObject();
        }

        @Bean
        @Primary
        public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory);
        }

        @Bean
        @Primary
        public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier("db1") DataSource dataSource) {
            return new DataSourceTransactionManager(dataSource);
        }
    }

    @Configuration
    @MapperScan(basePackages = "cn.reddata.plus.www.domain.mapper.click", sqlSessionTemplateRef = "sqlSessionTemplate2")
    public class Db2 {

        @Bean
        public SqlSessionFactory sqlSessionFactory2(@Qualifier("db2") DataSource dataSource) throws Exception {
            //mybatis应该使用  SqlSessionFactoryBean
            //SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();

            //mybatis-plus应该使用  MybatisSqlSessionFactoryBean  否则无法使用baseMapper
            MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
            sqlSessionFactory.setDataSource(dataSource);
            sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                    .getResources("classpath*:/mappers/click/*.xml"));
            //添加分页功能================================================================================================
            sqlSessionFactory.setPlugins(new Interceptor[]{clickPaginationInterceptor()});
            return sqlSessionFactory.getObject();
        }
        @Bean
        public SqlSessionTemplate sqlSessionTemplate2(@Qualifier("sqlSessionFactory2") SqlSessionFactory sqlSessionFactory) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory);
        }

        @Bean
        public DataSourceTransactionManager dataSourceTransactionManager2(@Qualifier("db2") DataSource dataSource) {
            return new DataSourceTransactionManager(dataSource);
        }
    }
}


 启动类:

SpringBoot多数据源方案_第3张图片

此方法注意事项:

 1,博主整合的是clickhouse和mysql数据源,要注意分包路径,这里有个需要注意的地方就是druid-spring-boot-starter连接池需要使用高版本的,不然不支持clickhouse数据库:

2, 分页插件需要指定数据库:

3,分页功能还没测试,依照之前的经验,click的分页需要自定义扩展。后续有空完善下这个。 

二:AOP动态配置数据源方式:

pom:


        UTF-8
        UTF-8
        1.8
        1.1.9
        2.7.0
    

    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-devtools
            runtime
        
        
            mysql
            mysql-connector-java
            runtime
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
            com.baomidou
            mybatis-plus-boot-starter
            2.1.9
        

        
        
            com.alibaba
            druid-spring-boot-starter
            ${druid.version}
        

        
            io.springfox
            springfox-swagger2
            ${swagger.version}
        
        
            io.springfox
            springfox-swagger-ui
            ${swagger.version}
        

        
            org.springframework.boot
            spring-boot-starter-aop
        
    

yml:

spring:
  datasource:
      druid:
          db1:
              username: root
              password: 123456
              driver-class-name: com.mysql.jdbc.Driver
              url: jdbc:mysql:///db1
              initialSize: 5
              minIdle: 5
              maxActive: 20
          db2:
              username: root
              password: 123456
              driver-class-name: com.mysql.jdbc.Driver
              url: jdbc:mysql:///db2
              initialSize: 5
              minIdle: 5
              maxActive: 20

目录结构:

SpringBoot多数据源方案_第4张图片

核心config类:

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

    DataSourceEnum value() default DataSourceEnum.DB1;
}
@Component
@Slf4j
@Aspect
@Order(-1)
public class DataSourceAspect {

    @Pointcut("@within(com.seawaterbt.ssm.annotation.DataSource) || @annotation(com.seawaterbt.ssm.annotation.DataSource)")
    public void pointCut(){

    }

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

    @After("pointCut()")
    public void doAfter(){
        DataSourceContextHolder.clear();
    }
}
@Configuration
public class DruidConfiguration {

    @Bean
    public ServletRegistrationBean startViewServlet(){
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
        // IP白名单
        servletRegistrationBean.addInitParameter("allow","127.0.0.1");
        // IP黑名单(共同存在时,deny优先于allow)
        servletRegistrationBean.addInitParameter("deny","127.0.0.1");
        //控制台管理用户
        servletRegistrationBean.addInitParameter("loginUsername","admin");
        servletRegistrationBean.addInitParameter("loginPassword","123456");
        //是否能够重置数据
        servletRegistrationBean.addInitParameter("resetEnable","false");
        return servletRegistrationBean;
    }

    @Bean
    public FilterRegistrationBean statFilter(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        //添加过滤规则
        filterRegistrationBean.addUrlPatterns("/*");
        //忽略过滤的格式
        filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return filterRegistrationBean;
    }
}


import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.MybatisConfiguration;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.mapper.LogicSqlInjector;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import com.seawaterbt.ssm.enums.DataSourceEnum;
import com.seawaterbt.ssm.multiple.MultipleDataSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
@MapperScan("com.seawaterbt.ssm.mapper*")
public class MyBatiesPlusConfiguration {

    /*
     * 分页插件,自动识别数据库类型
     * 多租户,请参考官网【插件扩展】
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 开启 PageHelper 的支持
        paginationInterceptor.setLocalPage(true);
        return paginationInterceptor;
    }

    /**
     * SQL执行效率插件
     */
    @Bean
    @Profile({"dev","qa"})// 设置 dev test 环境开启
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        performanceInterceptor.setMaxTime(1000);
        performanceInterceptor.setFormat(true);
        return performanceInterceptor;
    }

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

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

    /**
     * 动态数据源配置
     * @return
     */
    @Bean
    @Primary
    public DataSource multipleDataSource(@Qualifier("db1") DataSource db1, @Qualifier("db2") DataSource db2) {
        MultipleDataSource multipleDataSource = new MultipleDataSource();
        Map< Object, Object > targetDataSources = new HashMap<>();
        targetDataSources.put(DataSourceEnum.DB1.getValue(), db1);
        targetDataSources.put(DataSourceEnum.DB2.getValue(), db2);
        //添加数据源
        multipleDataSource.setTargetDataSources(targetDataSources);
        //设置默认数据源
        multipleDataSource.setDefaultTargetDataSource(db1);
        return multipleDataSource;
    }

    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(multipleDataSource(db1(),db2()));
        //sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*/*Mapper.xml"));

        MybatisConfiguration configuration = new MybatisConfiguration();
        //configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setCacheEnabled(false);
        sqlSessionFactory.setConfiguration(configuration);
        sqlSessionFactory.setPlugins(new Interceptor[]{ //PerformanceInterceptor(),OptimisticLockerInterceptor()
                paginationInterceptor() //添加分页功能
        });
        //sqlSessionFactory.setGlobalConfig(globalConfiguration());
        return sqlSessionFactory.getObject();
    }

    /*@Bean
    public GlobalConfiguration globalConfiguration() {
        GlobalConfiguration conf = new GlobalConfiguration(new LogicSqlInjector());
        conf.setLogicDeleteValue("-1");
        conf.setLogicNotDeleteValue("1");
        conf.setIdType(0);
        //conf.setMetaObjectHandler(new MyMetaObjectHandler());
        conf.setDbColumnUnderline(true);
        conf.setRefresh(true);
        return conf;
    }*/
}

public enum DataSourceEnum {

    DB1("db1"),DB2("db2");

    private String value;

    DataSourceEnum(String value){this.value=value;}

    public String getValue() {
        return value;
    }
}
public class DataSourceContextHolder {

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

    /**
     *  设置数据源
     * @param db
     */
    public static void setDataSource(String db){
        contextHolder.set(db);
    }

    /**
     * 取得当前数据源
     * @return
     */
    public static String getDataSource(){
        return contextHolder.get();
    }

    /**
     * 清除上下文数据
     */
    public static void clear(){
        contextHolder.remove();
    }
}
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class MultipleDataSource extends AbstractRoutingDataSource {

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

启动类:

SpringBoot多数据源方案_第5张图片

使用注解方式:

@Override
    @DataSource(DataSourceEnum.DB2)
    public boolean insert(Teacher entity) {
        return super.insert(entity);
    }

三:使用dynamic框架

pom:


        1.8
        1.0.29
        4.1
        3.1.1
        1.4.0
        3.1.0
    

    
        
            org.springframework.boot
            spring-boot-starter-actuator
        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            mysql
            mysql-connector-java
            runtime
        

        
        
            com.alibaba
            druid-spring-boot-starter
            1.2.6
        

        
            com.baomidou
            dynamic-datasource-spring-boot-starter
            3.2.0
        

        
            ru.yandex.clickhouse
            clickhouse-jdbc
            0.3.0
        

        
            com.baomidou
            mybatis-plus-boot-starter
            ${mybatis-plus.version}
        

        
            com.baomidou
            mybatis-plus-generator
            ${mybatis-plus.version}
        

        
        
            com.baomidou
            mybatis-plus-generator
            3.4.1
        
    

yml:

spring:
  autoconfigure:
    exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
  datasource:
    dynamic:
      primary: master
      strict: false
      datasource:
        master:
          url: jdbc:mysql://localhost:3306/reddata?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=true&serverTimezone=UTC
          username: root
          password: root
          driver-class-name: com.mysql.cj.jdbc.Driver
        click:
          url: jdbc:clickhouse://
          driverClassName: ru.yandex.clickhouse.ClickHouseDriver
          initialSize: 10
          maxActive: 100
          minIdle: 10
          maxWait: 6000
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000;config.decrypt=true;config.decrypt.key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKPYsCl3alwZlRb1vKoFdVu0LP3Nm/+vH5iOWxI83pkUbrQc13Lxz/VT3D+H+ziaUpUsA+ZjG4iZGTDJWZnP8kcCAwEAAQ==
      initialSize: 10
      minIdle: 10
      maxActive: 500
      maxWait: 60000
      testOnReturn: false
      testOnBorrow: false
      testWhileIdle: true
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 30000
      poolPreparedStatements: true
      validationQuery: select 'x'
      maxPoolPreparedStatementPerConnectionSize: 50
      filters: config,stat

目录结构:

SpringBoot多数据源方案_第6张图片

 核心congfig:

package cn.reddata.plus.www.config;

import com.baomidou.mybatisplus.core.parser.ISqlParser;
import com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
//import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

import java.util.ArrayList;
import java.util.List;

/**
 * MyBatisPlus 配置
 * 

* 创建人:Aries-li
* 创建时间:2019-06-14 10:40
*

* 修改人:
* 修改时间:
* 修改备注:
*

*/ @Configuration @MapperScan(basePackages = {"cn.reddata.plus.www.domain.mapper"}) public class MyBatisPlusConfig { /** * 分页插件 * @author :Aries-li
* @date :2019-06-14 10:43
*

*/ @Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); List sqlParserList = new ArrayList<>(); // 攻击 SQL 阻断解析器、加入解析链 作用!阻止恶意的全表更新删除 sqlParserList.add(new BlockAttackSqlParser()); paginationInterceptor.setSqlParserList(sqlParserList); return paginationInterceptor; } /** * 乐观锁 * @author :Aries-li
* @date :2019-06-14 10:55
*

*/ @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } }

package cn.reddata.plus.www.config;

import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Druid监控配置,使用基于Java代码实现的servlet和filter
 * 

* 具体实现参考 *
* 基于注解的配置StatView的Servlet *

*

* 创建人:Aries-li
* 创建时间:2018-11-10 13:43
*

* 修改人:
* 修改时间:
* 修改备注:
*

*/ @Configuration @Slf4j public class DruidMonitorConfig { /** * 注册ServletRegistrationBean * @return */ @Bean public ServletRegistrationBean registrationBean() { //org.springframework.boot.context.embedded.ServletRegistrationBean提供类的进行注册. ServletRegistrationBean bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*"); /** 初始化参数配置,initParams**/ //白名单 bean.addInitParameter("allow", "127.0.0.1");//多个ip逗号隔开 //IP黑名单 (存在共同时,deny优先于allow) : 如果满足deny的话提示:Sorry, you are not permitted to view this page. //bean.addInitParameter("deny", "192.168.1.110"); //登录查看信息的账号密码. bean.addInitParameter("loginUsername", "admin"); bean.addInitParameter("loginPassword", "123456"); //是否能够重置数据. bean.addInitParameter("resetEnable", "false"); return bean; } /** * 注册FilterRegistrationBean * @return */ @Bean public FilterRegistrationBean druidStatFilter() { FilterRegistrationBean bean = new FilterRegistrationBean<>(new WebStatFilter()); //添加过滤规则. bean.addUrlPatterns("/*"); //添加不需要忽略的格式信息. bean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); return bean; } }

启动类:

package cn.reddata.plus.www;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableTransactionManagement
public class SpringBootShiroApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootShiroApplication.class, args);
    }

}

使用方法:

/**
     * 主键查询用户信息
     *
     * @param id
     * @return
     */

    @DS("click")
    @InterceptorIgnore(tenantLine = "true")
    Order findById(@Param("id") long id);

此方法注意事项:

1,

2, 3,记得删调掉之前druid连接池的相关配置信息。

 写在结束的总结:

        整合多数据源这个需求还是频率挺高的,技术这行,活到老学到老,目前三种方式的分页功能还未测试,如有问题后续补上哈,欢迎点赞订阅。

你可能感兴趣的:(spring,boot,mysql,clickonce,后端)