SSM项目配置多数据源

配置单数据源

配置多数据源

  • 简介:该方案是基于注解、切面的方式实现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=******
  1. applicationContext-db.xml的配置


          
    
    

    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        

        
        
        
        
        
        
        
        
        
        
        
        
    

    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    

    
        
        
        
            
                
                
                
            
        
    

    
    
        
        
        
        
        
            
                classpath:com/fei/demo/mapper/*.xml
            
        
    

    
    
        
    
    


  1. 编写DataSourceRouter
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DataSourceRouter extends AbstractRoutingDataSource{

       @Override
       protected Object determineCurrentLookupKey() {
              String dataSource = HandleDataSource.getDataSource();
              return  dataSource;
       }
}
  1. 编写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();
       }
}
  1. 编写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();
}
  1. 编写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 ;
    }
}

  1. Dao层使用DataSource注解,不加注解使用的是默认的数据源
@Repository
@Mapper
@DataSource("dataSource2")
public interface Test2Dao{

       testList();
}

@Repository
@Mapper
@DataSource("dataSource1")
public interface Test1Dao{

       testList();
}

  1. 至此SSM配置多数据源成功

你可能感兴趣的:(SSM项目配置多数据源)