作者:码农教程
出自:码农教程
原文:manongjc.com/detail/14-ucsldoihyzmwcui.html
当项目中存在多数据源时,就涉及到数据源的动态切换,通过研究,特此记录一下。
1,maven依赖
<!-数据库连接->
<依赖性>
<groupId> com.oracle </ groupId>
<artifactId> ojdbc6 </ artifactId>
<version> 11.2.0.4 </ version>
<scope>运行时</ scope>
</ dependency>
<!-数据库连接池->
<依赖性>
<groupId> com.alibaba </ groupId>
<artifactId> druid-spring-boot-starter </ artifactId>
<version> 1.1.10 </ version>
</ dependency>
<依赖性>
<groupId> org.springframework.boot </ groupId>
<artifactId> spring-boot-starter-jdbc </ artifactId>
</ dependency>
<!-aop->
<依赖性>
<groupId> org.springframework.boot </ groupId>
<artifactId> spring-boot-starter-aop </ artifactId>
</ dependency>
2,多数据源信息配置
#多数据源测试
弹簧:
数据源:
德鲁伊:
主:
驱动程序-类-名称:oracle.jdbc.driver.OracleDriver
用户名:test
密码:测试
网址:jdbc:oracle:thin:@ // ip1:1521 / orcl
slave:
驱动程序-类-名称:oracle.jdbc.driver.OracleDriver
用户名:test
密码:测试
网址:jdbc:oracle:thin:@ // ip2:1521 / orcl
3,数据源配置信息转换成实体类
@ConfigurationProperties(prefix =“ spring.datasource.druid” )
@数据
@零件
公共 类DataSourceProperties {
私有Map <String,String> master;
私有Map <String,String>从属;
}
4,动态数据源切换类
公共 类DynamicDataSource扩展AbstractRoutingDataSource {
私有 静态 最终ThreadLocal <String> contextHolder = new ThreadLocal <> ();
公开DynamicDataSource(DataSource defaultTargetDataSource,Map <Object,Object> targetDataSources){
super .setDefaultTargetDataSource(defaultTargetDataSource);
超级.setTargetDataSources(targetDataSources);
超级.afterPropertiesSet();
}
@Override
受保护的对象defineCurrentLookupKey(){
return getDataSource();
}
公共 静态 无效setDataSource(String dataSource){
contextHolder.set(dataSource);
}
公共 静态字符串getDataSource(){
return contextHolder.get();
}
公共 静态 无效clearDataSource(){
contextHolder.remove();
}
}
5,多数据源配置类
@Configuration
公共 类DynamicDataSourceConfig {
@豆角,扁豆
公共数据源主控(@Autowired DataSourceProperties dataSourceProperties){
DruidDataSource druidDataSource =新的DruidDataSource();
映射<String,String> master = dataSourceProperties.getMaster();
druidDataSource.setUsername(master.get( “ username” ));
druidDataSource.setPassword(master.get( “ password” ));
druidDataSource.setUrl(master.get( “ url” ));
//其他参数配置省略
返回druidDataSource;
}
@豆角,扁豆
公用DataSource从属(@Autowired DataSourceProperties dataSourceProperties){
DruidDataSource druidDataSource =新的DruidDataSource();
映射<String,String> slave = dataSourceProperties.getSlave();
druidDataSource.setUsername(slave.get( “ username” ));
druidDataSource.setPassword(slave.get( “ password” ));
druidDataSource.setUrl(slave.get( “ url” ));
//其他参数配置省略
返回druidDataSource;
}
@豆角,扁豆
@主
公共DynamicDataSource数据源(数据源主数据源,数据源从数据){
映射<Object,Object> map = new HashMap <>(4 );
map.put( “ master” ,master);
map.put( “ slave” ,slave);
返回 新的DynamicDataSource(master,map);
}
}
6,自定义@DataSource注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @ interface数据源{
字符串name()默认为“ master” ;
}
7,Aop切面类配置
@零件
@方面
公共 类DataSourceAspect {
@Pointcut( “ @annotation(com.zxgeo.sso.muiltDatasource.anons.DataSource)” )
公共 无效dataSourcePointCut(){}
@Around(value =“ dataSourcePointCut()” )
围绕(ProceedingJoinPoint点)的公共对象抛出Throwable {
MethodSignature签名= (MethodSignature)point.getSignature();
方法method = signature.getMethod();
数据源的dataSource = method.getAnnotation(数据源。类);
如果(dataSource == null ){
DynamicDataSource.setDataSource( “ master” );
}其他{
DynamicDataSource.setDataSource(dataSource.name());
}
尝试{
return point.proceed();
}最后{
DynamicDataSource.clearDataSource();
}
}
}
8,启动配置注解信息,重要(不然运行会报错)
@SpringBootApplication(排除= {DataSourceAutoConfiguration。类})
9,测试
(1),服务层(此处没有使用mybatis)
@Service
公共 类TestService {
@Autowired
私有javax.sql.DataSource dataSource;
@数据源
公共Map <String,Object> getMasterDataSource()抛出SQLException {
连接连接= dataSource.getConnection();
映射<String,Object>映射;
尝试(PreparedStatement prepareStatement
= connection.prepareStatement(“ SELECT * FROM AA WHERE A = 10001” )){
ResultSet resultSet = prepareStatement.executeQuery ();
map = new HashMap <> ();
同时(resultSet.next()){
map.put( “ A”,resultSet.getString(“ A” ));
map.put( “ B”,resultSet.getString(“ B” ));
map.put( “ C”,resultSet.getString(“ C” ));
}
}
返回地图
}
@DataSource(name =“ slave” )
public Map <String,Object> getSlaveDataSource()引发SQLException {
连接连接= dataSource.getConnection();
映射<String,Object>映射;
尝试(PreparedStatement prepareStatement
= connection.prepareStatement(“ SELECT * FROM AA WHERE A = 10002” )){
ResultSet resultSet = prepareStatement.executeQuery ();
map = new HashMap <> ();
同时(resultSet.next()){
map.put( “ A”,resultSet.getString(“ A” ));
map.put( “ B”,resultSet.getString(“ B” ));
map.put( “ C”,resultSet.getString(“ C” ));
}
}
返回地图
}
}
(2),单元测试
@SpringBootTest
@RunWith(SpringRunner。类)
类SsoApplicationTests {
@Autowired
私有 TestService testService;
@测试
公共 无效muliDatasorce()抛出SQLException {
映射<String,Object> masterDataSourceUrl = testService.getMasterDataSource();
System.out.println(masterDataSourceUrl);
映射<String,Object> slaveDataSourceUrl = testService.getSlaveDataSource();
System.out.println(slaveDataSourceUrl);
}
}
(3),结果: