关于Spring Boot动态数据源的实现方法,我将介绍如何使用Mybatis和Druid实现,下面是详细步骤:
1. 引入相关依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
2. 添加配置文件
spring:
datasource:
dynamic:
ds1: # 数据源1
url: jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
initial-size: 5
min-idle: 3
max-active: 20
validation-query: SELECT 1
test-while-idle: true
time-between-eviction-runs-millis: 60000
ds2: # 数据源2
url: jdbc:mysql://localhost:3306/db2?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
initial-size: 5
min-idle: 3
max-active: 20
validation-query: SELECT 1
test-while-idle: true
time-between-eviction-runs-millis: 60000
3. 创建动态数据源
@Configuration
@EnableTransactionManagement
public class DynamicDataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.dynamic")
public Map<String, DataSource> dataSourceMap() {
return new LinkedHashMap<>();
}
@Bean
public DataSource dynamicDataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
Map<String, DataSource> dataSourceMap = dataSourceMap();
dynamicDataSource.setTargetDataSources(dataSourceMap);
dynamicDataSource.setDefaultTargetDataSource(dataSourceMap.get("ds1"));
return dynamicDataSource;
}
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dynamicDataSource());
return sqlSessionFactoryBean.getObject();
}
@Bean
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dynamicDataSource());
}
}
4. 创建动态数据源的工具类
public class DataSourceContextHolder {
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
public static void setDataSourceType(String dataSourceType) {
CONTEXT_HOLDER.set(dataSourceType);
}
public static String getDataSourceType() {
return CONTEXT_HOLDER.get();
}
public static void clearDataSourceType() {
CONTEXT_HOLDER.remove();
}
}
5. 创建数据源切换的AOP拦截器
@Aspect
@Component
public class DataSourceAspect {
@Pointcut("@annotation(com.example.datasource.annotation.DataSource)")
public void dataSourcePointcut() {
}
@Around("dataSourcePointcut()")
public Object doAround(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
DataSource dataSource = signature.getMethod().getAnnotation(DataSource.class);
if (dataSource != null) {
DataSourceContextHolder.setDataSourceType(dataSource.value().toString());
}
try {
return point.proceed();
} finally {
DataSourceContextHolder.clearDataSourceType();
}
}
}
6. 在Service层指定数据源
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@DataSource(DataSourceEnum.DS2)
public List<User> getUsers() {
return userMapper.selectUsers();
}
}
其中,DataSourceEnum
为一个自定义的枚举类,用于枚举不同的数据源。
示例1:添加用户数据到数据源1
在测试类中使用@DataSource(DataSourceEnum.DS1)
注解指定数据源1,并执行保存用户数据的操作:
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
@DataSource(DataSourceEnum.DS1)
public void testAddUser() {
User user = new User();
user.setUsername("test_user1");
user.setPassword("test_password1");
userService.addUser(user);
}
}
示例2:获取用户数据从数据源2
在测试类中使用@DataSource(DataSourceEnum.DS2)
注解指定数据源2,并执行获取用户数据的操作:
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
@DataSource(DataSourceEnum.DS2)
public void testGetUsers() {
List<User> userList = userService.getUsers();
Assert.assertEquals(1, userList.size());
}
}
以上就是Spring Boot动态数据源的实现方法,希望能够帮助到你。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springboot 动态数据源的实现方法(Mybatis+Druid) - Python技术站