springboot 使用mybatis1.3.2和druid-spring-boot-starter1.2.16和spring-boot-starter-parent2.3.9.RELEASE编写一个mybatis的动态连接程序,可随时切换连接源,其中需要准备一个默认mysql库,用于存放动态连接用户与密码的库,连接到这个默认的库之后使用mybatis查询出所有默认的库来进行动态连接其他库,通过传入的指定字符串来判断是要写换哪个数据源,并且不使用配置文件的方式来决定,指定通过传入的额参数决定,请问这个程序该怎么编写
时间: 2024-02-15 18:02:00 浏览: 81
通过springboot+mybatis+druid配置动态数据源
好的,根据您的需求,我为您编写了一个使用 MyBatis 和 Druid 连接池的动态连接程序,能够随时切换连接源,通过传入的参数来决定使用哪个数据源。具体实现步骤如下:
1. 在默认的 MySQL 库中创建一个表,用于存储动态连接用户和密码信息。示例 SQL 语句如下:
```sql
CREATE TABLE dynamic_datasource (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
url VARCHAR(100) NOT NULL,
username VARCHAR(50) NOT NULL,
password VARCHAR(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
```
2. 在项目中添加依赖,包括 MyBatis、Druid 和 MySQL 驱动等。示例 pom.xml 文件如下:
```xml
<dependencies>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</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>
<version>8.0.23</version>
</dependency>
</dependencies>
```
3. 在 application.yml 中配置 Druid 数据源。示例配置如下:
```yaml
spring:
datasource:
druid:
url: jdbc:mysql://localhost:3306/default_db?useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
```
4. 创建一个动态连接工具类 DynamicDataSourceUtils,用于动态创建数据源、切换数据源等操作。示例代码如下:
```java
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.datasource.DataSourceFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class DynamicDataSourceUtils extends AbstractRoutingDataSource {
private static final ThreadLocal<String> dataSourceKey = new ThreadLocal<>();
private static Map<Object, Object> targetDataSources = new HashMap<>();
@Autowired
private DataSourceFactory dataSourceFactory;
@Override
protected Object determineCurrentLookupKey() {
return getDataSourceKey();
}
public static String getDataSourceKey() {
return dataSourceKey.get();
}
public static void setDataSourceKey(String key) {
dataSourceKey.set(key);
}
public void addTargetDataSource(String key, String url, String username, String password) {
DruidDataSource dataSource = (DruidDataSource) dataSourceFactory.getDataSource();
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setInitialSize(5);
dataSource.setMinIdle(5);
dataSource.setMaxActive(20);
dataSource.setTestWhileIdle(false);
dataSource.setTestOnBorrow(false);
dataSource.setTestOnReturn(false);
dataSource.setValidationQueryTimeout(1);
dataSource.setValidationQuery("SELECT 1");
dataSource.setPoolPreparedStatements(false);
targetDataSources.put(key, dataSource);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
public void addTargetDataSource(String key, DataSource dataSource) {
targetDataSources.put(key, dataSource);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
public void removeTargetDataSource(String key) {
targetDataSources.remove(key);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
public List<Map<String, Object>> getDefaultDataSources() {
String sql = "SELECT name, url, username, password FROM dynamic_datasource";
try (Connection conn = this.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
return SqlUtils.resultSetToList(rs);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
```
5. 创建一个数据源切换的切面 DynamicDataSourceAspect,用于在需要切换数据源的方法上切换数据源。示例代码如下:
```java
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class DynamicDataSourceAspect {
@Autowired
private DynamicDataSourceUtils dataSourceUtils;
@Before("@annotation(ds)")
public void switchDataSource(JoinPoint joinPoint, DataSource ds) {
String dsKey = ds.value();
if (!DynamicDataSourceUtils.getDataSourceKey().equals(dsKey)) {
DynamicDataSourceUtils.setDataSourceKey(dsKey);
}
}
}
```
6. 在需要切换数据源的方法上添加 @DataSource 注解,指定要切换到哪个数据源。示例代码如下:
```java
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Map;
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user")
@DataSource("source1")
List<Map<String, Object>> getUsers();
}
```
7. 在代码中调用 UserMapper 的 getUsers 方法,传入指定的 @DataSource 注解值即可切换数据源。示例代码如下:
```java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public List<Map<String, Object>> getUsers(String dataSourceKey) {
DynamicDataSourceUtils.setDataSourceKey(dataSourceKey);
return userMapper.getUsers();
}
}
```
这样,就可以通过传入参数来动态切换数据源了。
阅读全文