配置:
application.yml spring: datasource: ####写数据源 update: jdbc-url: jdbc:mysql://192.168.100.150:8066/test driver-class-name: com.mysql.jdbc.Driver username: root password: root ###读数据源 select: jdbc-url: jdbc:mysql://192.168.100.150:8066/test driver-class-name: com.mysql.jdbc.Driver username: user password: user type: com.alibaba.druid.pool.DruidDataSource
配置读写数据源:
DataSourceConfig.java /** * 配置读写数据源 */ @Configuration public class DataSourceConfig { @Bean(name = "selectDataSource") @ConfigurationProperties(prefix = "spring.datasource.select") public DataSource dataSource1() { return DataSourceBuilder.create().build(); } @Bean(name = "updateDataSource") @ConfigurationProperties(prefix = "spring.datasource.update") public DataSource dataSource2() { return DataSourceBuilder.create().build(); } }
保存本地数据源:
DataSourceContextHolder.java /** * 保存本地多数据源 */ @Component @Lazy(false) public class DataSourceContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); // 设置数据源类型 public static void setDbType(String dbType) { contextHolder.set(dbType); } public static String getDbType() { return contextHolder.get(); } public static void clearDbType() { contextHolder.remove(); } }
配置动态切换数据源类:
DynamicDataSource.java /** * 该类继承自 AbstractRoutingDataSource 类,在访问数据库时会调用该类的 determineCurrentLookupKey() 方法获取数据库实例的 key */ @Component @Primary public class DynamicDataSource extends AbstractRoutingDataSource { private static final Logger logger = LoggerFactory.getLogger(DynamicDataSource.class); @Autowired @Qualifier("selectDataSource") private DataSource selectDataSource; @Autowired @Qualifier("updateDataSource") private DataSource updateDataSource; /** * 返回生效的数据源名称 */ @Override protected Object determineCurrentLookupKey() { logger.info("DataSourceContextHolder:{}", DataSourceContextHolder.getDbType()); return DataSourceContextHolder.getDbType(); } /** * 配置使用的数据源信息,如果不存在就使用默认的数据源 */ @Override public void afterPropertiesSet() { Map<Object, Object> map = new HashMap<>(); map.put("selectDataSource", selectDataSource); map.put("updateDataSource", updateDataSource); //注册数据源 setTargetDataSources(map); setDefaultTargetDataSource(updateDataSource); super.afterPropertiesSet(); } }
AOP配置:
DataSourceAOP.java @Aspect @Component @Lazy(false) // Order设定AOP执行顺序 使之在数据库事务上先执行 @Order(0) public class DataSourceAOP { private static final Logger logger = LoggerFactory.getLogger(DataSourceAOP.class); //横切点 @Before("execution(* com.yk.service.*.*(..))") public void process(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); if (methodName.startsWith("get") || methodName.startsWith("count") || methodName.startsWith("find") || methodName.startsWith("list") || methodName.startsWith("select") || methodName.startsWith("check")) { DataSourceContextHolder.setDbType("selectDataSource"); logger.info("使用的是读数据源:selectDataSource"); } else { DataSourceContextHolder.setDbType("updateDataSource"); logger.info("使用的是写数据源:updateDataSource"); } } }
application.ymlspring: datasource:####写数据源 update: jdbc-url:jdbc:mysql://192.168.100.150:8066/test driver-class-name:com.mysql.jdbc.Driver username:root password:root###读数据源 select: jdbc-url:jdbc:mysql://192.168.100.150:8066/test driver-class-name:com.mysql.jdbc.Driver username:user password:user type:com.alibaba.druid.pool.DruidDataSource