# ssm-dynamic-datasource
**Repository Path**: it_freshman/ssm-dynamic-datasource
## Basic Information
- **Project Name**: ssm-dynamic-datasource
- **Description**: ssm-dynamic-datasource
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2021-04-29
- **Last Updated**: 2021-08-05
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# ssm-动态连接池
## 项目介绍
ssm整合动态连接池.
### 原理
在使用jdbc时,会通过`DataSource.getConnection()`获取数据源连接信息 ,这里主要通过spring`AbstractRoutingDataSource`重写`getConnection()`来实现动态数据源切换。
### 自定义 DynamicRoutingDataSource extends AbstractRoutingDataSource动态数据源
```java
//org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {
@Override
public Connection getConnection() throws SQLException {
return determineTargetDataSource().getConnection();
}
protected DataSource determineTargetDataSource() {
//数据库连接池的key, 来确定实际使用的连接池
Object lookupKey = determineCurrentLookupKey();
DataSource dataSource = this.resolvedDataSources.get(lookupKey);
if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
dataSource = this.resolvedDefaultDataSource;
}
return dataSource;
}
//由子类实现, 通过动态设置该值来打到动态切换数据源的功能
protected abstract Object determineCurrentLookupKey();
}
//自定义 DynamicRoutingDataSource
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
//通过 threadlocal,来设置当前 连接池key
return DynamicRoutingDataSourceKeyHolder.getDataSource();
}
}
```
### dynamicRoutingDataSource初始化
```xml
```
### 整合mybatis - 注入动态连接池
```xml
```
## 实现
### 01_manual 业务代码中,显示指定数据源
```java
public class GoodsServiceImpl implements IGoodsService {
public int add(Goods goods) {
//threadlocal 手动指定 连接池id -- goodsDb
DynamicRoutingDataSourceKeyHolder.putDataSource("goodsDb");
return dao.insertGoods(goods);
}
}
public class OrderServiceImpl implements IOrderService {
public int add(Order order) {
//threadlocal 手动指定 连接池id --- orderDb
DynamicRoutingDataSourceKeyHolder.putDataSource("orderDb");
return dao.insertOrder(order);
}
}
```
### 02_aop_anno 通过aop+注解指定连接池
#### mapper上添加注解
## 排坑-事务
多数据源, 使用事务之后,较之动态数据源aop的切面更先执行。
而事务执行时,会执行geconnection,导致动态数据源切面,即使更新了连接池id, 也无法实现目标功能。