java框架 动态切换数据库_mybatis多数据库动态切换实现

本文介绍了如何在Java应用中实现在运行时动态切换数据库,主要涉及自定义注解、线程局部变量、重写Spring的AbstractRoutingDataSource以及使用AOP进行数据源设置。通过这些步骤,可以在不同方法中灵活选择不同的数据库连接。
摘要由CSDN通过智能技术生成

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 ThreadLocalcontextHolder = 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);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值