看了有些多数据源的整合文章,感觉有点乱,所以自己记录一下以后总会用得到。
别问问什么投原创,我找的几个例子页面找不到了!!!真的!!!
鞠躬了!
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency>
spring: datasource: db1: #实操以及展示 driver-class-name-: com.mysql.jdbc.Driver jdbc-url: jdbc:mysql://192.168.1.11:3306/js1?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true username: root password: w123!! db2: #机考 driver-class-name: com.ibm.db2.jcc.DB2Driver jdbc-url: jdbc:db2://192.168.1.134:50000/w username: db2admin password: "db2admin"
这部分是借鉴的!!!(抄的)
public class DataSourceConstants { public final static String MASTER = "db1"; public final static String SLAVE = "db2"; }
这部分是也借鉴的!!!(也是抄的)
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DynamicDataSourceContextHolder.getContextKey(); } } class DynamicDataSourceContextHolder { /* 动态数据源名称上下文*/ private static final ThreadLocal<String> DATASOURCE_CONTEXT_KEY_HOLDER = new ThreadLocal<>(); /* 设置/切换数据源*/ public static void setContextKey(String key) { System.out.println("切换数据源"+key); DATASOURCE_CONTEXT_KEY_HOLDER.set(key); } /* 获取数据源名称 */ public static String getContextKey() { String key = DATASOURCE_CONTEXT_KEY_HOLDER.get(); return key == null ? DataSourceConstants.MASTER : key; } /*删除当前数据源名称*/ public static void removeContextKey() { DATASOURCE_CONTEXT_KEY_HOLDER.remove(); } }
@Target({ElementType.METHOD,ElementType.TYPE}) 可应用于方法、类、接口
import com.windmill.datasource.DataSourceConstants; import java.lang.annotation.*; @Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface DataSource { //默认主数据源 String value() default DataSourceConstants.MASTER; }
@Configuration 定义配置类
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class }) 自定义数据源,不使用SpringBoot默认配置
@Primary 默认优先选择
@ConfigurationProperties 设置默认的属性值
@Bean 将实例注入到Spring IOC
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; @Configuration @EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class }) public class DynamicDataSourceConfig { @Bean(DataSourceConstants.MASTER) @ConfigurationProperties(prefix = "spring.datasource.db1") public DataSource masterDataSource() { return DataSourceBuilder.create().build(); } @Bean(DataSourceConstants.SLAVE) @ConfigurationProperties(prefix = "spring.datasource.db2") public DataSource slaveDataSource() { return DataSourceBuilder.create().build(); } @Bean @Primary public DataSource dynamicDataSource() { Map<Object, Object> dataSourceMap = new HashMap<>(2); dataSourceMap.put(DataSourceConstants.MASTER, masterDataSource()); dataSourceMap.put(DataSourceConstants.SLAVE, slaveDataSource()); //设置动态数据源 DynamicDataSource dynamicDataSource = new DynamicDataSource(); dynamicDataSource.setTargetDataSources(dataSourceMap); dynamicDataSource.setDefaultTargetDataSource(masterDataSource()); return dynamicDataSource; } }
不解释了 :-)
import com.windmill.annotations.DataSource; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import java.util.Objects; @Aspect @Component public class DynamicDataSourceAspect { //拦截注解方法 @Pointcut("@annotation(com.windmill.annotations.DataSource)") public void dataSourcePointCut() { } @Around("dataSourcePointCut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { String dsKey = this.getDSAnnotation(joinPoint).value(); DynamicDataSourceContextHolder.setContextKey(dsKey); try { return joinPoint.proceed(); } catch (Exception ex) { throw ex; } finally { DynamicDataSourceContextHolder.removeContextKey(); } } /** * 根据类或方法获取数据源注解 */ private DataSource getDSAnnotation(ProceedingJoinPoint joinPoint) { //mybatis生成的代理类,所以获取它的接口来获取DbAnnotation注解信息 Class<?> targetClass = joinPoint.getTarget().getClass().getInterfaces()[0]; DataSource dsAnnotation = targetClass.getAnnotation(DataSource.class); // 先判断类的注解,再判断方法注解 if (Objects.nonNull(dsAnnotation)) { return dsAnnotation; } else { MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); DataSource annotation = methodSignature.getMethod().getAnnotation(DataSource.class); return annotation; } } }
@Mapper public interface BaseInfoMapper { @DataSource(DataSourceConstants.SLAVE) List<Baseinfo> selectUserList(@Param("orgId") orgId); }