1、第一个数据源
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close" lazy-init="false"> <property name="url" value="${xinfang.url}"/> <property name="username" value="${xinfang.username}"/> <property name="password" value="${xinfang.password}"/> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <!-- 配置初始化大小、最小、最大 --> <property name="initialSize" value="5"/> <property name="minIdle" value="20"/> <property name="maxActive" value="100"/> <!-- 配置获取连接等待超时的时间 --> <property name="maxWait" value="30000"/> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="90000"/> <property name="validationQuery" value="SELECT 1"/> <property name="testWhileIdle" value="true"/> <property name="testOnBorrow" value="false"/> <property name="testOnReturn" value="false"/> <!-- 打开PSCache,并且指定每个连接上PSCache的大小 --><!-- 如果用Oracle,则把poolPreparedStatements配置为true,mysql可以配置为false。分库分表较多的数据库,建议配置为false。 --> <property name="poolPreparedStatements" value="false"/> <property name="maxPoolPreparedStatementPerConnectionSize" value="20"/> <!-- 配置监控统计拦截的filters,wall用于防止sql注入,stat用于统计分析 --> <property name="filters" value="wall"/> <property name="proxyFilters"> <list> <ref bean="statfilter"/> <ref bean="logFilter"/> </list> </property> </bean>
2、第二个数据源
<bean id="dataSource_mid" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close" lazy-init="false"> <property name="url" value="${xinfang.mid.url}"/> <property name="username" value="${xinfang.mid.username}"/> <property name="password" value="${xinfang.mid.password}"/> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <!-- 配置初始化大小、最小、最大 --> <property name="initialSize" value="5"/> <property name="minIdle" value="20"/> <property name="maxActive" value="100"/> <!-- 配置获取连接等待超时的时间 --> <property name="maxWait" value="30000"/> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="90000"/> <property name="validationQuery" value="SELECT 1"/> <property name="testWhileIdle" value="true"/> <property name="testOnBorrow" value="false"/> <property name="testOnReturn" value="false"/> <!-- 打开PSCache,并且指定每个连接上PSCache的大小 --><!-- 如果用Oracle,则把poolPreparedStatements配置为true,mysql可以配置为false。分库分表较多的数据库,建议配置为false。 --> <property name="poolPreparedStatements" value="false"/> <property name="maxPoolPreparedStatementPerConnectionSize" value="20"/> <!-- 配置监控统计拦截的filters,wall用于防止sql注入,stat用于统计分析 --> <property name="filters" value="wall"/> <property name="proxyFilters"> <list> <ref bean="statfilter"/> <ref bean="logFilter"/> </list> </property> </bean>
3、
<!-- 配置动态配置数据源 --> <bean id ="dynamicDataSource" class= "com.shencai.xf.common.dynamicDataSource.DynamicDataSource"> <!-- 默认使用dataSource1的数据源 --> <property name ="defaultTargetDataSource" ref="dataSource"></property> <property name ="targetDataSources"> <map key-type ="java.lang.String"> <entry key= "dataSource" value-ref="dataSource"></entry> <entry key= "dataSource_mid" value-ref="dataSource_mid"></entry> </map> </property> </bean>
4、注解实现和数据源切换代码
@Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DataSource { String value() default "datasource"; }
public class DataSourceContextHolder { /** * 默认数据源 */ public static final String DEFAULT_DS = "dataSource"; private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); // 设置数据源名 public static void setDB(String dbType) { System.out.println("切换到{"+dbType+"}数据源"); contextHolder.set(dbType); } // 获取数据源名 public static String getDB() { //return (contextHolder.get()); if(contextHolder.get()==null){ return DEFAULT_DS; }else{ return (contextHolder.get()); } } // 清除数据源名 public static void clearDB() { contextHolder.remove(); } }
@Order(2) public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { System.out.println("当前数据源为"+DataSourceContextHolder.getDB()); return DataSourceContextHolder.getDB(); } }
@Order(1) @Aspect public class DynamicDataSourceAspect { //使用DS注解动作之后清除 @After("@annotation(com.shencai.xf.common.dynamicDataSource.DataSource)") public void afterSwitchDS(JoinPoint point){ System.out.println("清除当前数据源"+DataSourceContextHolder.getDB()); DataSourceContextHolder.clearDB(); } //使用DS注解动态切换 @Before("@annotation(com.shencai.xf.common.dynamicDataSource.DataSource)") public void beforeSwitchDS(JoinPoint point){ //获得当前访问的class Class<?> className = point.getTarget().getClass(); //获得访问的方法名 String methodName = point.getSignature().getName(); //得到方法的参数的类型 Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes(); String dataSource = DataSourceContextHolder.DEFAULT_DS; try { // 得到访问的方法对象 Method method = className.getMethod(methodName, argClass); // 判断是否存在@DS注解 if (method.isAnnotationPresent(DataSource.class)) { DataSource annotation = method.getAnnotation(DataSource.class); // 取出注解中的数据源名 dataSource = annotation.value(); } } catch (Exception e) { e.printStackTrace(); } // 切换数据源 DataSourceContextHolder.setDB(dataSource); } }
5、