zoukankan      html  css  js  c++  java
  • Druid动态数据源配置

    上文已经讲了单个数据源的Druid的配置(http://www.cnblogs.com/nbfujx/p/7686634.html

    Druid动态数据源配置 主要是继承AbstractRoutingDataSource再通过AOP来实现动态数据源切换

     Druid动态数据源的使用(基于原先的程序调整

     使用步骤:

    1.调整配置属性文件:mybatis.properties (增加DataSource连接参数)

     1 master.driver=com.mysql.jdbc.Driver
     2 master.url=jdbc:mysql://127.0.0.1:3306/jawavesys
     3 master.username=root
     4 master.password=jawave88
     5 #定义初始连接数
     6 master.initialSize=0
     7 #定义最大连接数
     8 master.maxActive=20
     9 #定义最大空闲
    10 master.maxIdle=20
    11 #定义最小空闲
    12 master.minIdle=1
    13 #定义最长等待时间
    14 master.maxWait=60000
    15 
    16 
    17 slave.driver=com.mysql.jdbc.Driver
    18 slave.url=jdbc:mysql://127.0.0.1:3306/jawave_eform
    19 slave.username=root
    20 slave.password=jawave88
    21 #定义初始连接数
    22 slave.initialSize=0
    23 #定义最大连接数
    24 slave.maxActive=20
    25 #定义最大空闲
    26 slave.maxIdle=20
    27 #定义最小空闲
    28 slave.minIdle=1
    29 #定义最长等待时间
    30 slave.maxWait=60000
    View Code

    2.调整SPRING配置文件:spring-base.xml

      1 <?xml version="1.0" encoding="UTF-8"?>
      2 <beans xmlns="http://www.springframework.org/schema/beans"
      3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
      4        xmlns:context="http://www.springframework.org/schema/context"
      5        xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
      6        xmlns:aop="http://www.springframework.org/schema/aop"
      7        xsi:schemaLocation="http://www.springframework.org/schema/beans
      8                         http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
      9                         http://www.springframework.org/schema/context  
     10                         http://www.springframework.org/schema/context/spring-context-3.1.xsd  
     11                         http://www.springframework.org/schema/tx
     12                         http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
     13                         http://www.springframework.org/schema/aop 
     14                         http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
     15                         http://www.springframework.org/schema/mvc  
     16                         http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
     17 
     18 
     19     <context:component-scan base-package="com.goku.druid.demo">
     20         <context:exclude-filter type="annotation"
     21                                 expression="org.springframework.stereotype.Controller" />
     22     </context:component-scan>
     23 
     24     <!-- 引入配置文件 -->
     25     <bean id="propertyConfigurer"
     26           class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
     27         <property name="location" value="classpath:mybatis.properties" />
     28     </bean>
     29 
     30     <bean id="masterDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
     31         <property name="driverClassName" value="${master.driver}" />
     32         <property name="url" value="${master.url}" />
     33         <property name="username" value="${master.username}" />
     34         <property name="password" value="${master.password}" />
     35         <!-- 初始化连接大小 -->
     36         <property name="initialSize" value="${master.initialSize}"></property>
     37         <!-- 连接池最大数量 -->
     38         <property name="maxActive" value="${master.maxActive}"></property>
     39         <!-- 连接池最大空闲 -->
     40         <property name="maxIdle" value="${master.maxIdle}"></property>
     41         <!-- 连接池最小空闲 -->
     42         <property name="minIdle" value="${master.minIdle}"></property>
     43         <!-- 获取连接最大等待时间 -->
     44         <property name="maxWait" value="${master.maxWait}"></property>
     45         <!-- 这里配置提交方式,默认就是TRUE,可以不用配置 -->
     46         <property name="defaultAutoCommit" value="true" />
     47         <!-- 验证连接有效与否的SQL,不同的数据配置不同 -->
     48         <property name="validationQuery" value="select 1 " />
     49         <!--通过别名的方式配置扩展插件,监控统计用的filter:stat  日志用的filter:log4j  防御sql注入的filter:wall-->
     50         <property name="filters" value="stat,log4j" />
     51         <property name="proxyFilters">
     52             <list>
     53                 <ref bean="stat-filter" />
     54                 <ref bean="log-filter"/>
     55             </list>
     56         </property>
     57     </bean>
     58 
     59     <bean id="slaveDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
     60         <property name="driverClassName" value="${slave.driver}" />
     61         <property name="url" value="${slave.url}" />
     62         <property name="username" value="${slave.username}" />
     63         <property name="password" value="${slave.password}" />
     64         <!-- 初始化连接大小 -->
     65         <property name="initialSize" value="${slave.initialSize}"></property>
     66         <!-- 连接池最大数量 -->
     67         <property name="maxActive" value="${slave.maxActive}"></property>
     68         <!-- 连接池最大空闲 -->
     69         <property name="maxIdle" value="${slave.maxIdle}"></property>
     70         <!-- 连接池最小空闲 -->
     71         <property name="minIdle" value="${slave.minIdle}"></property>
     72         <!-- 获取连接最大等待时间 -->
     73         <property name="maxWait" value="${slave.maxWait}"></property>
     74         <!-- 这里配置提交方式,默认就是TRUE,可以不用配置 -->
     75         <property name="defaultAutoCommit" value="true" />
     76         <!-- 验证连接有效与否的SQL,不同的数据配置不同 -->
     77         <property name="validationQuery" value="select 1 " />
     78         <!--通过别名的方式配置扩展插件,监控统计用的filter:stat  日志用的filter:log4j  防御sql注入的filter:wall-->
     79         <property name="filters" value="stat,log4j" />
     80         <property name="proxyFilters">
     81             <list>
     82                 <ref bean="stat-filter" />
     83                 <ref bean="log-filter"/>
     84             </list>
     85         </property>
     86     </bean>
     87 
     88     <bean id="dataSource" class="com.goku.druid.demo.util.DynamicDataSource">
     89         <property name="targetDataSources">
     90             <map key-type="java.lang.String">
     91                 <!-- master -->
     92                 <entry key="master" value-ref="masterDataSource"/>
     93                 <!-- slave -->
     94                 <entry key="slave" value-ref="slaveDataSource"/>
     95             </map>
     96         </property>
     97         <property name="defaultTargetDataSource" ref="masterDataSource"/>
     98     </bean>
     99 
    100     <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
    101     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    102         <property name="dataSource" ref="dataSource" />
    103         <!-- 自动扫描mapping.xml文件 -->
    104         <property name="mapperLocations" value="classpath:mapping/**/*.xml"></property>
    105     </bean>
    106 
    107     <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
    108     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    109         <property name="basePackage" value="com.goku.druid.demo.mapper" />
    110         <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    111     </bean>
    112 
    113     <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->
    114     <bean id="transactionManager"
    115           class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    116         <property name="dataSource" ref="dataSource" />
    117     </bean>
    118 
    119     <!-- 开启事务注解驱动 -->
    120     <tx:annotation-driven  transaction-manager="transactionManager"/>
    121 
    122     <!-- 为业务逻辑层的方法解析@DataSource注解  为当前线程的routeholder注入数据源key -->
    123     <bean id="dataSourceAspect" class="com.goku.druid.demo.util.DataSourceAspect" />
    124     <aop:config proxy-target-class="true">
    125         <aop:aspect id="dataSourceAspect" ref="dataSourceAspect" order="1">
    126             <aop:pointcut id="tx" expression="execution(* com.goku.druid.demo.service..*.*(..)) "/>
    127             <aop:before pointcut-ref="tx" method="before" />
    128         </aop:aspect>
    129     </aop:config>
    130 
    131     <!--监控统计-->
    132     <bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter">
    133         <property name="slowSqlMillis" value="10000" />
    134         <property name="logSlowSql" value="true" />
    135     </bean>
    136 
    137     <!--日志-->
    138     <bean id="log-filter" class="com.alibaba.druid.filter.logging.Log4jFilter">
    139         <property name="statementExecutableSqlLogEnable" value="true" />
    140     </bean>
    141 
    142 
    143 </beans>
    View Code

    3.接下写AbstractRoutingDataSource继承类

    package com.goku.druid.demo.util;
    
    import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
    
    /**
     * Created by nbfujx on 2017/10/18.
     */
    public class DynamicDataSource extends AbstractRoutingDataSource  {
    
        @Override
        protected Object determineCurrentLookupKey() {
            return DataSourceHolder.getDataSource();
        }
    
    }

    4.接下来写切面实现类

    package com.goku.druid.demo.util;
    
    import java.lang.reflect.Method;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.reflect.MethodSignature;
    
    /**
     *  Created by nbfujx on 2017/10/18.
     */
    public class DataSourceAspect {
    
    
        /**
         * 在dao层方法之前获取datasource对象之前在切面中获取数据源
         */
        public void before(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("method"+ m.getName());
                if (m != null && m.isAnnotationPresent(DataSource.class)) {
                    DataSource data = m.getAnnotation(DataSource.class);
                    System.out.println("dataSource:"+data.value());
                    DataSourceHolder.putDataSource(data.value());
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    5.还有拿到数据元的类

    package com.goku.druid.demo.util;
    
    /**
     * Created by nbfujx on 2017/10/18.
     */
    public class DataSourceHolder {
        public static final ThreadLocal<String> holder = new ThreadLocal<String>();
    
        /**
         * 设置数据源
         */
        public static void putDataSource(String datasource) {
            holder.set(datasource);
        }
    
        /**
         * 获取数据源
         */
        public static String getDataSource() {
            return holder.get();
        }
    
    
        /**
         * 清除数据源
         */
        public static void clearDataSource() {
            holder.remove();
        }
    }

    6.DataSource数据源注解类

    package com.goku.druid.demo.util;
    
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Target;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    
    /**
     * Created by nbfujx on 2017/10/18.
     */
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface DataSource {
        String value();
    }

    7.在service层进行数据源注解切换

    package com.goku.druid.demo.service;
    
    import com.goku.druid.demo.model.FormElement;
    import com.goku.druid.demo.model.UserWithBLOBs;
    import com.goku.druid.demo.util.DataSource;
    
    /**
     * Created by nbfujx on 2017-10-18.
     */
    public interface UserService {
        @DataSource("master")
        UserWithBLOBs selectByPrimaryKey(String id);
    
        @DataSource("slave")
        FormElement selectByPrimaryKey2(Integer id);
    }

    GITHUB

    github :  https://github.com/nbfujx/learn-java-demo/tree/master/Goku.Dynamic.DruidDemo

  • 相关阅读:
    bp算法原理
    bp算法
    Python之简单的神经网络
    人工智能教程
    clickhouse的windowFunnel(漏斗)
    Hihocoder 1079 离散化
    Hihocoder 1063 缩地
    md5
    搜索引擎 中文分词
    Hihocoder 1059 String Matching Content Length
  • 原文地址:https://www.cnblogs.com/nbfujx/p/7687788.html
Copyright © 2011-2022 走看看