springboot 使用mybatis1.3.2和druid-spring-boot-starter1.2.16和spring-boot-starter-parent2.3.9.RELEASE编写一个mybatis的动态连接程序,可随时切换连接源,其中需要准备一个默认mysql库,用于存放动态连接用户与密码的库,连接到这个默认的库之后使用mybatis查询出所有默认的库来进行动态连接其他库,请问这个程序该怎么编写
时间: 2024-02-15 13:01:46 浏览: 105
首先,需要在`pom.xml`中添加以下依赖:
```xml
<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.16</version>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
```
接下来,需要在`application.properties`中配置默认的MySQL数据源,以及Druid的数据源和监控页面的访问路径:
```properties
# 默认MySQL数据源
spring.datasource.url=jdbc:mysql://localhost:3306/default_db
spring.datasource.username=root
spring.datasource.password=root
# Druid数据源
spring.datasource.druid.url=jdbc:mysql://localhost:3306/default_db
spring.datasource.druid.username=root
spring.datasource.druid.password=root
# Druid监控页面
spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.stat-view-servlet.reset-enable=false
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=admin
```
然后,需要定义一个`DataSourceConfig`类,用于创建Druid数据源:
```java
@Configuration
public class DataSourceConfig {
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
```
接下来,需要定义一个`DynamicDataSource`类,用于动态切换数据源。这里使用`AbstractRoutingDataSource`实现:
```java
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSource();
}
}
```
`DataSourceContextHolder`类用于保存当前线程使用的数据源:
```java
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
public static String getDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
}
```
然后,需要定义一个`DynamicDataSourceConfig`类,用于创建动态数据源:
```java
@Configuration
public class DynamicDataSourceConfig {
@Autowired
private DataSource dataSource;
@Bean
public DynamicDataSource dynamicDataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
Map<Object, Object> dataSourceMap = new HashMap<>();
dataSourceMap.put("default", dataSource);
dynamicDataSource.setTargetDataSources(dataSourceMap);
dynamicDataSource.setDefaultTargetDataSource(dataSource);
return dynamicDataSource;
}
}
```
在`DynamicDataSourceConfig`中,我们将默认的MySQL数据源添加到了动态数据源中。
接下来,需要定义一个`MapperScannerConfig`类,用于扫描mapper接口:
```java
@Configuration
@MapperScan(basePackages = "com.example.mapper")
public class MapperScannerConfig {
}
```
最后,需要定义一个`DynamicDataSourceAspect`类,用于在方法执行前切换数据源:
```java
@Aspect
@Component
public class DynamicDataSourceAspect {
@Pointcut("@annotation(com.example.annotation.DataSource)")
public void dataSourcePointCut() {
}
@Around("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) {
DataSourceContextHolder.setDataSource(dataSource.value());
}
try {
return point.proceed();
} finally {
DataSourceContextHolder.clearDataSource();
}
}
}
```
`@DataSource`注解用于指定数据源,这里的实现是在方法上使用注解。
现在,就可以开始编写动态连接程序了。首先,需要定义一个mapper接口:
```java
public interface DataSourceMapper {
List<Map<String, Object>> listDataSource();
}
```
该接口用于查询默认的MySQL库中保存的动态连接用户与密码信息。
然后,需要定义一个`DataSourceService`类,用于获取动态连接用户与密码信息,并根据信息动态创建数据源:
```java
@Service
public class DataSourceService {
@Autowired
private DataSourceMapper dataSourceMapper;
public void dynamicDataSource(String username, String password) throws Exception {
// 查询数据源信息
List<Map<String, Object>> list = dataSourceMapper.listDataSource();
// 动态创建数据源
for (Map<String, Object> map : list) {
String dataSourceName = (String) map.get("data_source_name");
String dataSourceUrl = (String) map.get("data_source_url");
String dataSourceUsername = (String) map.get("data_source_username");
String dataSourcePassword = (String) map.get("data_source_password");
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl(dataSourceUrl);
dataSource.setUsername(dataSourceUsername);
dataSource.setPassword(dataSourcePassword);
// 将数据源添加到动态数据源中
Map<Object, Object> targetDataSources = DynamicDataSourceHolder.getTargetDataSources();
targetDataSources.put(dataSourceName, dataSource);
DynamicDataSourceHolder.setTargetDataSources(targetDataSources);
}
// 切换数据源
String dataSourceName = "dynamic_" + System.currentTimeMillis();
String dataSourceUrl = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&maxReconnects=10";
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl(dataSourceUrl);
dataSource.setUsername(username);
dataSource.setPassword(password);
// 将数据源添加到动态数据源中
Map<Object, Object> targetDataSources = DynamicDataSourceHolder.getTargetDataSources();
targetDataSources.put(dataSourceName, dataSource);
DynamicDataSourceHolder.setTargetDataSources(targetDataSources);
// 切换数据源
DynamicDataSourceHolder.setDataSource(dataSourceName);
}
}
```
在`DataSourceService`中,我们首先查询默认的MySQL库中保存的动态连接用户与密码信息,然后根据信息动态创建数据源,并将数据源添加到动态数据源中,最后切换数据源。
最后,我们可以在需要动态切换数据源的方法上添加`@DataSource`注解,指定数据源:
```java
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@DataSource("default")
public List<User> listUser() {
return userMapper.listUser();
}
@DataSource("dynamic")
public List<User> listDynamicUser() {
return userMapper.listUser();
}
}
```
这样,就完成了动态连接程序的编写。
阅读全文