spring boot多数据源动态切换代码实例

这篇文章主要介绍了spring boot多数据源动态切换代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

当项目中存在多数据源时,就涉及到数据源的动态切换,通过研究,特此记录一下。

1、maven依赖

<!--数据库连接-->

<dependency>

<groupId>com.oracle</groupId>

<artifactId>ojdbc6</artifactId>

<version>11.2.0.4</version>

<scope>runtime</scope>

</dependency>

<!--数据库连接池->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>druid-spring-boot-starter</artifactId>

<version>1.1.10</version>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-jdbc</artifactId>

</dependency>

<!--aop->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-aop</artifactId>

</dependency>

2、多数据源信息配置

#多数据源测试

spring:

datasource:

druid:

master:

driver-class-name: oracle.jdbc.driver.OracleDriver

username: test

password: test

url: jdbc:oracle:thin:@//ip1:1521/orcl

slave:

driver-class-name: oracle.jdbc.driver.OracleDriver

username: test

password: test

url: jdbc:oracle:thin:@//ip2:1521/orcl

3、数据源配置信息转换成实体类

@ConfigurationProperties(prefix = "spring.datasource.druid")

@Data

@Component

public class DataSourceProperties {

private Map<String,String>master;

private Map<String,String>slave;

}

4、动态数据源切换类

public class DynamicDataSource extends AbstractRoutingDataSource {

private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {

super.setDefaultTargetDataSource(defaultTargetDataSource);

super.setTargetDataSources(targetDataSources);

super.afterPropertiesSet();

}

@Override

protected Object determineCurrentLookupKey() {

return getDataSource();

}

public static void setDataSource(String dataSource) {

contextHolder.set(dataSource);

}

public static String getDataSource() {

return contextHolder.get();

}

public static void clearDataSource() {

contextHolder.remove();

}

}

5、多数据源配置类

@Configuration

public class DynamicDataSourceConfig {

@Bean

public DataSource master(@Autowired DataSourceProperties dataSourceProperties){

DruidDataSource druidDataSource = new DruidDataSource();

Map<String, String> master = dataSourceProperties.getMaster();

druidDataSource.setUsername(master.get("username"));

druidDataSource.setPassword(master.get("password"));

druidDataSource.setUrl(master.get("url"));

//其他参数配置 省略

return druidDataSource;

}

@Bean

public DataSource slave(@Autowired DataSourceProperties dataSourceProperties){

DruidDataSource druidDataSource = new DruidDataSource();

Map<String, String> slave = dataSourceProperties.getSlave();

druidDataSource.setUsername(slave.get("username"));

druidDataSource.setPassword(slave.get("password"));

druidDataSource.setUrl(slave.get("url"));

//其他参数配置 省略

return druidDataSource;

}

@Bean

@Primary

public DynamicDataSource dataSource(DataSource master,DataSource slave){

Map<Object,Object>map = new HashMap<>(4);

map.put("master",master);

map.put("slave",slave);

return new DynamicDataSource(master,map);

}

}

6、自定义@DataSource注解

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface DataSource {

String name() default "master";

}

7、Aop切面类配置

@Component

@Aspect

public class DataSourceAspect {

@Pointcut("@annotation(com.zxgeo.sso.muiltDatasource.anons.DataSource)")

public void dataSourcePointCut(){}

@Around(value = "dataSourcePointCut()")

public Object around(ProceedingJoinPoint point) throws Throwable {

MethodSignature signature = (MethodSignature) point.getSignature();

Method method = signature.getMethod();

DataSource dataSource = method.getAnnotation(DataSource.class);

if(dataSource == null){

DynamicDataSource.setDataSource("master");

}else {

DynamicDataSource.setDataSource(dataSource.name());

}

try {

return point.proceed();

} finally {

DynamicDataSource.clearDataSource();

}

}

}

8、启动配置注解信息,重要(不然运行会报错)

@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})

9、测试

(1)、service层(此处没有使用mybatis)

@Service

public class TestService {

@Autowired

private javax.sql.DataSource dataSource;

@DataSource

public Map<String,Object> getMasterDataSource() throws SQLException {

Connection connection = dataSource.getConnection();

Map<String,Object> map;

try (PreparedStatement preparedStatement

= connection.prepareStatement("SELECT * FROM AA WHERE A=10001")) {

ResultSet resultSet = preparedStatement.executeQuery();

map = new HashMap<>();

while (resultSet.next()){

map.put("A",resultSet.getString("A"));

map.put("B",resultSet.getString("B"));

map.put("C",resultSet.getString("C"));

}

}

return map;

}

@DataSource(name = "slave")

public Map<String,Object> getSlaveDataSource() throws SQLException {

Connection connection = dataSource.getConnection();

Map<String,Object> map;

try (PreparedStatement preparedStatement

= connection.prepareStatement("SELECT * FROM AA WHERE A=10002")) {

ResultSet resultSet = preparedStatement.executeQuery();

map = new HashMap<>();

while (resultSet.next()){

map.put("A",resultSet.getString("A"));

map.put("B",resultSet.getString("B"));

map.put("C",resultSet.getString("C"));

}

}

return map;

}

}

(2)、单元测试

@SpringBootTest

@RunWith(SpringRunner.class)

class SsoApplicationTests {

@Autowired

private TestService testService;

@Test

public void muliDatasorce() throws SQLException {

Map<String, Object> masterDataSourceUrl = testService.getMasterDataSource();

System.out.println(masterDataSourceUrl);

Map<String, Object> slaveDataSourceUrl = testService.getSlaveDataSource();

System.out.println(slaveDataSourceUrl);

}

}

(3)、结果:

以上是 spring boot多数据源动态切换代码实例 的全部内容, 来源链接: utcz.com/z/341817.html

回到顶部