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

  • 相关阅读:
    Java异常处理和设计
    一次qps测试实践
    Alternate Task UVA
    Just Another Problem UVA
    Lattice Point or Not UVA
    Play with Floor and Ceil UVA
    Exploring Pyramids UVALive
    Cheerleaders UVA
    Triangle Counting UVA
    Square Numbers UVA
  • 原文地址:https://www.cnblogs.com/nbfujx/p/7687788.html
Copyright © 2011-2022 走看看