配置:
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
