mybatis多数据库动态切换实现

          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
         
       
       
                  
                classpath:conf.properties
           

       

   
 

        destroy-method="close">  
         
         
         
       
         
         
           
         
           
         
           
         
         
         
           
         
           
         
         
         
         
         
         
         
         
         
       
   

    
   






     
 
     
     
         
             
             
       
 
   
 
         

 





   








 


   


  
       
           
                            expression="execution(* com.tvjoy.btop.webapp..*.*(..))" />   
              
              
              
              
       

   

     


一、自定义一个注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


/**
 * RUNTIME 编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。
 * 
 * @author wanggang
 * 
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DataSource {
String value();
}


二、建立一个动态设置数据库的类

public class DBContextHolder {


/**
* 线程threadlocal
*/
private static ThreadLocal contextHolder = new ThreadLocal();


public static void putDataSource(String datasource) {
contextHolder.set(datasource);
}


public static String getDataSource() {
return contextHolder.get();
}
}


三、重写Spring框架里的AbstractRoutingDataSource类中的determineCurrentLookupKey

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;


public class DynamicDataSource extends AbstractRoutingDataSource {


/*
* (non-Javadoc)

* @see javax.sql.CommonDataSource#getParentLogger()
*/
@Override
public java.util.logging.Logger getParentLogger() {
// TODO Auto-generated method stub
return null;
}


/**

* override determineCurrentLookupKey
*


* Title: determineCurrentLookupKey
*


*


* Description: 自动查找datasource
*



* @return
*/
@Override
protected Object determineCurrentLookupKey() {
return DBContextHolder.getDataSource();
}


}


四、自定义一个组件用来可以动态设置数据库

import java.lang.reflect.Method;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class DynamicDataSourceAspect {
private static final Logger log = LoggerFactory
.getLogger(DynamicDataSourceAspect.class);


public DynamicDataSourceAspect() {
}


public void doBefore(JoinPoint point) {
Object target = point.getTarget();
// System.out.println(target.toString());
String method = point.getSignature().getName();
// System.out.println(method);
Class[] classz = target.getClass().getInterfaces();
Class[] parameterTypes = ((MethodSignature) point.getSignature())
.getMethod().getParameterTypes();
try {
Method m = classz[0].getMethod(method, parameterTypes);
// System.out.println(m.getName());
if (m != null && m.isAnnotationPresent(DataSource.class)) {
DataSource data = m.getAnnotation(DataSource.class);
DBContextHolder.putDataSource(data.value());
}


} catch (Exception e) {
e.printStackTrace();
}
}


public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
long time = System.currentTimeMillis();
Object retVal = pjp.proceed();
time = System.currentTimeMillis() - time;
log.debug("DoAround process time: {} ms", Long.valueOf(time));
return retVal;
}


public void doAfter(JoinPoint jp) {
log.debug("DoAfter method: {}.{}", jp.getTarget().getClass().getName(),
jp.getSignature().getName());
}


public void doThrowing(JoinPoint jp, Throwable ex) {
log.debug("DoThrowing method: {}.{} throw exception", jp.getTarget()
.getClass().getName(), jp.getSignature().getName());
log.debug("throwable{}", ex);
}
}

你可能感兴趣的:(数据库,java)