# SSM项目配置多数据源
**Repository Path**: fpfgitmy_admin/ssm-configuration-many-datasource
## Basic Information
- **Project Name**: SSM项目配置多数据源
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2021-04-28
- **Last Updated**: 2021-04-28
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
#### 配置多数据源
+ 简介:该方案是基于注解、切面的方式实现SSM多数据源
1. db.properties的配置
```
jdbc.url.db1=jdbc:mysql://ip1:3306/db1?useUnicode=true&characterEncoding=utf-8
jdbc.username.db1=root
jdbc.password.db1=******
jdbc.url.db2=jdbc:mysql://ip2:3306/db2?useUnicode=true&characterEncoding=utf-8
jdbc.username.db2=root
jdbc.password.db2=******
```
2. applicationContext-db.xml的配置
```
classpath:com/fei/demo/mapper/*.xml
```
3. 编写`DataSourceRouter`类
```
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DataSourceRouter extends AbstractRoutingDataSource{
@Override
protected Object determineCurrentLookupKey() {
String dataSource = HandleDataSource.getDataSource();
return dataSource;
}
}
```
4. 编写`HandleDataSource`类
```
public class HandleDataSource {
private static final ThreadLocal holder = new
ThreadLocal();
public static void setDataSource(String datasource) {
holder.set(datasource);
}
public static String getDataSource() {
return holder.get();
}
public static void clearDataSource() {
holder.remove();
}
}
```
5. 编写`DataSource`注解
```
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
String value();
}
```
6. 编写`DataSourceAspect`切面类
```
import java.lang.reflect.Method;
import java.text.MessageFormat;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.fei.demo.common.annotation.DataSource;
@Aspect
@Component
@Order(1)
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class DataSourceAspect {
static Logger logger = LoggerFactory.getLogger(DataSourceAspect.class);
// 拦截dao层的所有方法
@Pointcut("execution(* com.fei.demo.*.dao..*.*(..))")
public void aspect() {}
@Before("aspect()")
public void before(JoinPoint point) {
Class> target = point.getTarget().getClass();
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod() ;
DataSource dataSource = null ;
dataSource = this.getDataSource(target, method) ;
if(dataSource == null){
for (Class> clazz : target.getInterfaces()) {
dataSource = getDataSource(clazz, method);
if(dataSource != null){
break ;
}
}
}
if(dataSource != null && !"".equals(dataSource.value()) ){
HandleDataSource.setDataSource(dataSource.value());
}
}
@After("aspect()")
public void after(JoinPoint point) {
HandleDataSource.setDataSource(null);
}
public DataSource getDataSource(Class> target, Method method){
try {
Class>[] types = method.getParameterTypes();
Method m = target.getMethod(method.getName(), types);
if (m != null && m.isAnnotationPresent(DataSource.class)) {
return m.getAnnotation(DataSource.class);
}
if (target.isAnnotationPresent(DataSource.class)) {
return target.getAnnotation(DataSource.class);
}
} catch (Exception e) {
e.printStackTrace();
logger.error(MessageFormat.format("通过注解切换数据源时发生异常[class={0},method={1}]:"
, target.getName(), method.getName()),e) ;
}
return null ;
}
}
```
7. 在`Dao`层使用`DataSource`注解,不加注解使用的是默认的数据源
```
@Repository
@Mapper
@DataSource("dataSource2")
public interface Test2Dao{
testList();
}
```
```
@Repository
@Mapper
@DataSource("dataSource1")
public interface Test1Dao{
testList();
}
```
8. 至此`SSM`配置多数据源成功