zoukankan      html  css  js  c++  java
  • 切面和注解方式添加多个数据源

    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、

  • 相关阅读:
    SQL反模式学习笔记16 使用随机数排序
    SQL反模式学习笔记21 SQL注入
    SQL反模式学习笔记22 伪键洁癖,整理数据
    SQL反模式学习笔记18 减少SQL查询数据,避免使用一条SQL语句解决复杂问题
    SQL反模式学习笔记19 使用*号,隐式的列
    SQL反模式学习笔记17 全文搜索
    SQL反模式学习笔记20 明文密码
    (可发送)亿级流量APP,是怎么做前端性能测试自动化的?
    测试窝 高薪测试必备技能和 20+ 项目实战精华,好书免费领(限前 1000 名)!
    同样是断言,为何 Hamcrest 如此优秀?测试灵魂三问,该如何回答?
  • 原文地址:https://www.cnblogs.com/wmqiang/p/11678880.html
Copyright © 2011-2022 走看看