# 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`配置多数据源成功