springboot 配置多数据源
1. application.yml 配置
datasource: type: com.alibaba.druid.pool.DruidDataSource druid: znz: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://ip:3306/znz?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&autoReconnect=true username: username password: password big: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://ip:3306/bg_data1?useUnicode=true&characterEncoding=UTF8&zeroDateTimeBehavior=convertToNull&autoReconnect=true username: username password: password maxActive: 20 initialSize: 1 maxWait: 60000 minIdle: 1 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: select 'x' testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true maxOpenPreparedStatements: 20 stat-view-servlet: enabled: true url-pattern: /druid/* filter: stat: log-slow-sql: true slow-sql-millis: 1000 merge-sql: true wall: config: multi-statement-allow: true
2.代码
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.core.Ordered; import org.springframework.stereotype.Component; import java.lang.reflect.Method; /** * @version 数据源AOP * @Date 2019/04/23 */ @Component @Aspect public class DataSourceAspect implements Ordered { public static final Log log = LogFactory.getLog(DataSourceAspect.class); /** * @version 定义aop作用的注解 * @Date 2019/04/23 */ @Pointcut("@annotation(com.abcdpower.x.zcdatamanagement.common.dataSource.MyDataSource)")//注意:这里的xxxx代表的是上面public @interface DataSource这个注解DataSource的包名 public void dataSourcePointCut() { } /** * @version 执行前方法 * @Date 2019/04/23 */ @Before("dataSourcePointCut()") public void around(JoinPoint point) throws Throwable { // 获取MethodSignature MethodSignature signature = (MethodSignature) point.getSignature(); // 获取method Method method = signature.getMethod(); // 获取数据源的注解 MyDataSource ds = method.getAnnotation(MyDataSource.class); // 默认数据源znz if (ds == null) { DynamicDataSource.setDataSource(DataSourceNames.znz); } else { // 爬虫数据源 DynamicDataSource.setDataSource(DataSourceNames.bgData); } } /** * @version 释放数据源 * @Date 2019/04/23 */ @After("dataSourcePointCut()") public void release() { DynamicDataSource.clearDataSource(); } /** * @version 设置执行顺序 * @Date 2019/04/23 */ @Override public int getOrder() { return 1; } }
/** * @version 数据源常量 * @Date 2019/04/23 */ public interface DataSourceNames { String znz = "znz"; // 默认数据源 String bgData = "big"; // 爬虫数据源 }
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; /** * @version 存储数据源 * @Date 2019/04/23 */ public class DynamicDataSource extends AbstractRoutingDataSource { // 用来保存数据源与获取数据源 private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public DynamicDataSource(DataSource defaultTargetDataSource, Map<String, DataSource> targetDataSources) { super.setDefaultTargetDataSource(defaultTargetDataSource); // 设置默认数据源 super.setTargetDataSources(new HashMap<Object, Object>(targetDataSources)); // 设置目标数据源 super.afterPropertiesSet(); } /** * @version 获取数据源 * @Date 2019/04/23 */ @Override protected Object determineCurrentLookupKey() { return getDataSource(); } /** * @version 设置数据源 * @Date 2019/04/23 */ public static void setDataSource(String dataSource) { contextHolder.set(dataSource); } /** * @version 获取数据源 * @Date 2019/04/23 */ public static String getDataSource() { return contextHolder.get(); } /** * @version 清除数据源 * @Date 2019/04/23 */ public static void clearDataSource() { contextHolder.remove(); } }
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; 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.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; /** * @version 数据源配置类 * @Date 2019/04/23 */ @Configuration public class DynamicDataSourceConfig { /** * @version 默认数据源 * @Date 2019/04/23 */ @Primary @Bean @ConfigurationProperties("spring.datasource.druid.znz") public DataSource znzDataSource(){ return DruidDataSourceBuilder.create().build(); } /** * @version 爬虫数据源 * @Date 2019/04/23 */ @Bean @ConfigurationProperties("spring.datasource.druid.big") public DataSource bgDataDataSource(){ return DruidDataSourceBuilder.create().build(); } /** * @version 数据源Map * @Date 2019/04/23 */ @Bean(name = "dynamicDataSource") public DynamicDataSource dataSource(@Qualifier("znzDataSource") DataSource znzDataSource, @Qualifier("bgDataDataSource") DataSource bgDataDataSource) { // 新建数据源map Map<String, DataSource> targetDataSources = new HashMap<>(); targetDataSources.put(DataSourceNames.znz, znzDataSource); // 今日园商 targetDataSources.put(DataSourceNames.bgData, bgDataDataSource); // 爬虫 // 返回DynamicDataSource return new DynamicDataSource(znzDataSource, targetDataSources); } /** * @version SqlSessionFactory * @Date 2019/04/23 */ @Bean(name = "sqlSessionFactory") public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dynamicDataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); // 实例化SqlSessionFactoryBean bean.setDataSource(dynamicDataSource); // 设置数据源 bean.setMapperLocations( new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/**/*Mapper.xml")); // 定义mapper地址 return bean.getObject(); } /** * 配置事务管理器 */ @Bean public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception { return new DataSourceTransactionManager(dataSource); }
import java.lang.annotation.*; /** * @version 数据源注解 * @Date 2019/04/23 */ @Target({ ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyDataSource { String name() default ""; // 默认为空 }