SpringBoot_连接池_多数据源_Druid

多数据源实现

依赖pom.xml

	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>druid</artifactId>
	</dependency>
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>druid-spring-boot-starter</artifactId>
	</dependency>

配置文件bootstrap.yml

spring:
    datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.jdbc.Driver
        druid:
            first:  #数据源1
                url: jdbc:mysql://192.168.164.100:3306/renren_fast?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
                username: root
                password: qwe123
            second:  #数据源2
                url: jdbc:mysql://192.168.164.100:3306/kettle?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
                username: root
                password: qwe123
            initial-size: 10
            max-active: 100
            min-idle: 10
            max-wait: 60000
            pool-prepared-statements: true
            max-pool-prepared-statement-per-connection-size: 20
            time-between-eviction-runs-millis: 60000
            min-evictable-idle-time-millis: 300000
            validation-query: SELECT 1 FROM DUAL
            test-while-idle: true
            test-on-borrow: false
            test-on-return: false
            stat-view-servlet:
                enabled: true
                url-pattern: /druid/*
                #login-username: admin
                #login-password: admin
            filter:
                stat:
                    log-slow-sql: true
                    slow-sql-millis: 1000
                    merge-sql: true
                wall:
                    config:
                        multi-statement-allow: true

配置源码

    /**
     * 添加数据源
     * 
     * 
     * @author vander
     * @date 2019年3月29日
     */
    public interface DataSourceNames {
        String FIRST = "first";
        String SECOND = "second";
    }
    
    /**
     * 多数据源注解
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface DataSource {
        String name() default "";
    }
    
    /**
     * 多数据源,切面处理类
     */
    @Aspect
    @Component
    public class DataSourceAspect implements Ordered {
        protected Logger logger = LoggerFactory.getLogger(getClass());
    
        @Pointcut("@annotation(com.plxc.springboot.datasources.annotation.DataSource)")
        public void dataSourcePointCut() {
        }
    
        @Around("dataSourcePointCut()")
        public Object around(ProceedingJoinPoint point) throws Throwable {
            MethodSignature signature = (MethodSignature) point.getSignature();
            Method method = signature.getMethod();
    
            DataSource ds = method.getAnnotation(DataSource.class);
            if(ds == null){
                DynamicDataSource.setDataSource(DataSourceNames.FIRST);
                logger.debug("set datasource is " + DataSourceNames.FIRST);
            }else {
                DynamicDataSource.setDataSource(ds.name());
                logger.debug("set datasource is " + ds.name());
            }
    
            try {
                return point.proceed();
            } finally {
                DynamicDataSource.clearDataSource();
                logger.debug("clean datasource");
            }
        }
    
        @Override
        public int getOrder() {
            return 1;
        }
    }
    
    /**
     * 配置多数据源
     */
    @Configuration
    public class DynamicDataSourceConfig {
    
        @Bean
        @ConfigurationProperties("spring.datasource.druid.first")
        public DataSource firstDataSource(){
            return DruidDataSourceBuilder.create().build();
        }
    
        @Bean
        @ConfigurationProperties("spring.datasource.druid.second")
        public DataSource secondDataSource(){
            return DruidDataSourceBuilder.create().build();
        }
    
        @Bean(name = "kettleJdbcTemplate")
        public JdbcTemplate kettleJdbcTemplate(@Qualifier("secondDataSource") DataSource kettleSource) {
            return new JdbcTemplate(kettleSource);
        }
    
    
        @Bean
        @Primary
        public DynamicDataSource dataSource(DataSource firstDataSource, DataSource secondDataSource) {
            Map<String, DataSource> targetDataSources = new HashMap<>();
            targetDataSources.put(DataSourceNames.FIRST, firstDataSource);
            targetDataSources.put(DataSourceNames.SECOND, secondDataSource);
            return new DynamicDataSource(firstDataSource, targetDataSources);
        }
    }
    
    /**
     * 动态数据源
     */
    public class DynamicDataSource extends AbstractRoutingDataSource {
        private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
    
        public DynamicDataSource(DataSource defaultTargetDataSource, Map<String, DataSource> targetDataSources) {
            super.setDefaultTargetDataSource(defaultTargetDataSource);
            super.setTargetDataSources(new HashMap<>(targetDataSources));
            super.afterPropertiesSet();
        }
    
        @Override
        protected Object determineCurrentLookupKey() {
            return getDataSource();
        }
    
        public static void setDataSource(String dataSource) {
            contextHolder.set(dataSource);
        }
    
        public static String getDataSource() {
            return contextHolder.get();
        }
    
        public static void clearDataSource() {
            contextHolder.remove();
        }
    
    }
    
    /**
     * 测试
     */
    @Service
    public class DataSourceTestService {
        @Autowired
        private UserService userService;
    
        public UserEntity queryObject(Long userId){
            return userService.queryObject(userId);
        }
    
        @DataSource(name = DataSourceNames.SECOND)
        public UserEntity queryObject2(Long userId){
            return userService.queryObject(userId);
        }
    }

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
@Import({DynamicDataSourceConfig.class})
public class AppApplication extends SpringBootServletInitializer {

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

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(AppApplication.class);
	}
}

starter实现

依赖pom.xml

	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>druid</artifactId>
	</dependency>
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>druid-spring-boot-starter</artifactId>
	</dependency>
	<dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
    </dependency>
   <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

配置文件bootstrap.yml

  spring:
      datasource:
        druid:
          url: ${MYSQL_URL:jdbc:mysql://localhost:3306/tb_user?characterEncoding=utf-8}
          username: root
          password: mysql
          driverClassName: com.mysql.jdbc.Driver
          initialSize: 5  #初始建立连接数量
          minIdle: 5  #最小连接数量
          maxActive: 20 #最大连接数量
          maxWait: 10000  #获取连接最大等待时间,毫秒
          testOnBorrow: true #申请连接时检测连接是否有效
          testOnReturn: false #归还连接时检测连接是否有效
          timeBetweenEvictionRunsMillis: 60000 #配置间隔检测连接是否有效的时间(单位是毫秒)
          minEvictableIdleTimeMillis: 300000  #连接在连接池的最小生存时间(毫秒)
mybatis:
    mapperLocations: classpath:mapper/**/*.xml
    configuration:
        map-underscore-to-camel-case: true

配置源码

@MapperScan("com.plxc.ucenter.dao")
@EntityScan("com.plxc.framework.domain.ucenter")//扫描实体类
@SpringBootApplication
public class UcenterApplication {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(UcenterApplication.class, args);
    }
}

自定义实现

依赖pom.xml

	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>druid</artifactId>
	</dependency>

配置文件bootstrap.yml

//spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
//spring.datasource.driver-class-name=com.mysql.jdbc.Driver
//spring.datasource.url=jdbc:mysql://192.168.164.100:3306/renren_fast?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
//spring.datasource.username=root
//spring.datasource.password=qwe123
//spring.datasource.initialSize=5
//spring.datasource.minIdle=5
//spring.datasource.maxActive=20
//spring.datasource.maxWait=60000
//spring.datasource.timeBetweenEvictionRunsMillis=60000
//spring.datasource.minEvictableIdleTimeMillis=300000
//spring.datasource.validationQuery=SELECT 1
//spring.datasource.testWhileIdle=true
//spring.datasource.testOnBorrow=false
//spring.datasource.testOnReturn=false
//spring.datasource.poolPreparedStatements=true
//spring.datasource.filters=stat
//spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
//spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
//spring.datasource.useGlobalDataSourceStat=true

//spring: 
//	  datasource: 
//	    type: com.alibaba.druid.pool.DruidDataSource
//	    driver-class-name: com.mysql.jdbc.Driver
//	    url: jdbc:mysql://192.168.164.100:3306/renren_fast?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
//	    username: root
//	    password: qwe123
//	    initial-size: 5
//	    min-idle: 5
//	    max-active: 20
//	    max-wait: 60000
//	    time-between-eviction-runs-millis: 60000
//	    min-evictable-idle-time-millis: 300000
//	    validation-query: SELECT 1
//	    test-while-idle: true
//	    test-on-borrow: false
//	    test-on-return: false
//	    pool-prepared-statements: true
//	    filters: stat
//	    max-pool-prepared-statement-per-connection-size: 20
//	    connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
//	    use-global-data-source-stat: true

配置源码

/**
 * Druid配置中心
 *
 *
 * @author vander
 * @date 2018年11月20日
 */
@SuppressWarnings("all")
@Configuration
@ConditionalOnProperty(value="pingruan.base.enable-druid",havingValue="true")
public class DruidConfig {
	
	@Autowired
	BProperties bProperties;
	
	
    /**
     * @function 添加
     * @return
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druid(){
    	DruidDataSource datasource = new DruidDataSource();
    	openMultiStatement(datasource);
        return datasource;
    }

    //配置多sql执行  filters: stat
	private void openMultiStatement(DruidDataSource datasource) {
		WallConfig wc = new WallConfig();
    	wc.setMultiStatementAllow(true);
    	WallFilter wf = new WallFilter();
    	wf.setConfig(wc);
    	List<Filter> filters = new ArrayList<Filter>();
    	filters.add(wf);
    	datasource.setProxyFilters(filters);
	}

    //配置Druid的监控
    //1、配置一个管理后台的Servlet
    @Bean
    public ServletRegistrationBean statViewServlet(){
		ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        Map<String,String> initParams = new HashMap<>();
        initParams.put("loginUsername",bProperties.getDruidUserName());
        initParams.put("loginPassword",bProperties.getDruidPassword());
        initParams.put("allow",bProperties.getDruidAllowIps());//默认就是允许所有访问
        initParams.put("deny",bProperties.getDruidDenyIps());
        bean.setInitParameters(initParams);
        return bean;
    }

    //2、配置一个web监控的filter
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
        Map<String,String> initParams = new HashMap<>();
        initParams.put("exclusions","*.js,*.gif,*.png,*.css,*.ico,/druid/*");
        bean.setInitParameters(initParams);
        bean.setUrlPatterns(Arrays.asList("/*"));
        return  bean;
    }
}

@Component
@ConfigurationProperties(prefix="spring.datasource")
@Data
public class DruidProperties {
	
	private int initialSize;
    private int minIdle;
    private int maxActive;
    private int maxWait;
    private int timeBetweenEvictionRunsMillis;
    private int minEvictableIdleTimeMillis;
    private String validationQuery;
    private boolean testWhileIdle;
    private boolean testOnBorrow;
    private boolean testOnReturn;
    private boolean poolPreparedStatements;
    private int maxPoolPreparedStatementPerConnectionSize;
    private String filters;
    private String connectionProperties;
    private boolean useGlobalDataSourceStat;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值