SpringMvc 4.3 多数据源示例

来源:互联网 发布:2016团购份额CDICC数据 编辑:程序博客网 时间:2024/06/16 00:36
  由于每个框架不尽相同,所以以下配置仅供参考。我不喜欢说废话,废话说多了一没用,刚才好像打错了一个字,把一改成也,谢谢,好了,废话不多说,我们开始吧!

需呀配置以下文件:
- jdbc.properties
- springMvc-base.xml
- DataSource.class
- DataSourceAspect.class
- DynamicDataSource.class
- DynamicDataSourceHolder.class


jdbc.properties

######################                   ##     SqlServer     ##                   ######################driver=com.microsoft.sqlserver.jdbc.SQLServerDriverurl=jdbc:sqlserver://192.168.5.98:1433;databaseName=\u4f60\u731c\u6211\u7528\u7684\u4ec0\u4e48\u540d\u5b57username=sapassword=sa######################                   ##      Oracle       ##                   ######################driver_two=oracle.jdbc.driver.OracleDriverurl_two=jdbc:oracle:thin:@192.168.5.99:1521:ORCLusername_two=xxxxxxxpassword_two=xxxxxxxvalidationQuery_two:select 1 from dualfilters:statmaxActive:20initialSize:1maxWait:60000minIdle:10maxIdle:15timeBetweenEvictionRunsMillis:60000minEvictableIdleTimeMillis:300000validationQuery:select 1testWhileIdle:truetestOnBorrow:falsetestOnReturn:falsemaxOpenPreparedStatements:20removeAbandoned:trueremoveAbandonedTimeout:1800logAbandoned:true

springMvc-base.xml
这里只贴核心配置
两个druid 连接池配置

<!-- 配置数据源:阿里 druid数据库连接池 -->    <bean id="dataSource_sqlserver" class="com.alibaba.druid.pool.DruidDataSource"        destroy-method="close">        <!-- 数据库基本信息配置 -->        <property name="url" value="${url}" />        <property name="username" value="${username}" />        <property name="password" value="${password}" />        <property name="driverClassName" value="${driver}" />        <property name="filters" value="${filters}" />        <!-- 最大并发连接数 -->        <property name="maxActive" value="${maxActive}" />        <!-- 初始化连接数量 -->        <property name="initialSize" value="${initialSize}" />        <!-- 配置获取连接等待超时的时间 -->        <property name="maxWait" value="${maxWait}" />        <!-- 最小空闲连接数 -->        <property name="minIdle" value="${minIdle}" />        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->        <property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}" />        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->        <property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}" />        <property name="validationQuery" value="${validationQuery}" />        <property name="testWhileIdle" value="${testWhileIdle}" />        <property name="testOnBorrow" value="${testOnBorrow}" />        <property name="testOnReturn" value="${testOnReturn}" />        <property name="maxOpenPreparedStatements" value="${maxOpenPreparedStatements}" />        <!-- 打开removeAbandoned功能 -->        <property name="removeAbandoned" value="${removeAbandoned}" />        <!-- 1800秒,也就是30分钟 -->        <property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}" />        <!-- 关闭abanded连接时输出错误日志 -->        <property name="logAbandoned" value="${logAbandoned}" />    </bean>    <bean id="dataSource_oracle" class="com.alibaba.druid.pool.DruidDataSource"          destroy-method="close">        <!-- 数据库基本信息配置 -->        <property name="url" value="${url_two}" />        <property name="username" value="${username_two}" />        <property name="password" value="${password_two}" />        <property name="driverClassName" value="${driver_two}" />        <property name="filters" value="${filters}" />        <!-- 最大并发连接数 -->        <property name="maxActive" value="${maxActive}" />        <!-- 初始化连接数量 -->        <property name="initialSize" value="${initialSize}" />        <!-- 配置获取连接等待超时的时间 -->        <property name="maxWait" value="${maxWait}" />        <!-- 最小空闲连接数 -->        <property name="minIdle" value="${minIdle}" />        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->        <property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}" />        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->        <property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}" />        <property name="validationQuery" value="${validationQuery_two}" />        <property name="testWhileIdle" value="${testWhileIdle}" />        <property name="testOnBorrow" value="${testOnBorrow}" />        <property name="testOnReturn" value="${testOnReturn}" />        <property name="maxOpenPreparedStatements" value="${maxOpenPreparedStatements}" />        <!-- 打开removeAbandoned功能 -->        <property name="removeAbandoned" value="${removeAbandoned}" />        <!-- 1800秒,也就是30分钟 -->        <property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}" />        <!-- 关闭abanded连接时输出错误日志 -->        <property name="logAbandoned" value="${logAbandoned}" />    </bean>
<!--多数据源选择-->    <bean id="dataSource" class="com.googosoft.util.double_datasource.DynamicDataSource">        <property name="targetDataSources">            <map key-type="java.lang.String">                <entry value-ref="dataSource_sqlserver" key="dataSource_sqlserver"></entry>                <entry value-ref="dataSource_oracle" key="dataSource_oracle"></entry>            </map>        </property>    </bean>
<!-- 配置数据库注解aop -->    <!--多数据源选择-->    <bean id="dataSourceAspect" class="com.googosoft.util.double_datasource.DataSourceAspect"/>

这里多数据源选择 有一个aop的顺序,不要配置反了

    <aop:config>        <!-- id:事务切入点名称 expression:事务切入点正则表达式 -->        <aop:pointcut id="serviceMethods" expression="execution(* com.bjkjdx.serviceImpl..*.*(..))" />        <!--数据源选择切面,保证在事务开始之前执行-->        <!--<aop:advisor pointcut-ref="serviceMethods" advice-ref="txAdvice" />-->        <!--多数据源选择-->        <aop:advisor pointcut-ref="serviceMethods" advice-ref="dataSourceAspect" order="1" />        <aop:advisor pointcut-ref="serviceMethods" advice-ref="txAdvice" order="2" />    </aop:config><tx:advice id="txAdvice" transaction-manager="transactionManager">        <tx:attributes>            <!-- 以delete、insert、update、sava、do、go开头的所有方法采用只读型事务控制类型 -->            <tx:method name="delete*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />            <tx:method name="insert*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />            <tx:method name="update*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />            <tx:method name="save*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />            <tx:method name="do*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" timeout="10" />            <tx:method name="go*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" timeout="10" />            <!-- 以load、find、search、select、get开头的所有方法采用只读型事务控制类型 -->            <tx:method name="load*" propagation="SUPPORTS" read-only="true"/>            <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>            <tx:method name="search*" propagation="SUPPORTS" read-only="true"/>            <tx:method name="select*" propagation="SUPPORTS" read-only="true"/>            <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>            <tx:method name="*" propagation="SUPPORTS" read-only="true"/>        </tx:attributes>    </tx:advice>

然后是代码:(当然我现在的能力还写不出这么NX的代码,谢谢我曾经抄过的某位码神,实在是忘了抄的谁的了,囧)

DataSource.class
使用注解来动态切换数据源

@Documented@Retention(RUNTIME)@Target({ElementType.METHOD,ElementType.TYPE})public @interface DataSource {    String name();//    String name() default DataSource.dataSource_sqlserver;}

DataSourceAspect.class
监听springmvc框架数据源选择,在事务开始之前,进行数据源切换
这里配置默认的数据源

public class DataSourceAspect implements MethodBeforeAdvice,AfterReturningAdvice{    /*调用方法    * @DataSource(name= DataSourceAspect.dataSource_oracle)    * */    public static final String dataSource_sqlserver = "dataSource_sqlserver";    public static final String dataSource_oracle = "dataSource_oracle";    @Override    public void afterReturning(Object returnValue, Method method,                               Object[] args, Object target) throws Throwable {        DynamicDataSourceHolder.clearDataSourceType();    }    @Override    public void before(Method method, Object[] args, Object target)            throws Throwable {        //首先取类上的数据源        if(method.getDeclaringClass().isAnnotationPresent(DataSource.class) && !method.isAnnotationPresent(DataSource.class)) {            DataSource datasource = method.getDeclaringClass().getAnnotation(DataSource.class);            DynamicDataSourceHolder.setDataSourceType(datasource.name());            //方法上的数据源 优先级高于类上的        } else if (method.isAnnotationPresent(DataSource.class)) {            DataSource datasource = method.getAnnotation(DataSource.class);            DynamicDataSourceHolder.setDataSourceType(datasource.name());        }        else        {            DynamicDataSourceHolder.setDataSourceType(dataSource_sqlserver);        }    }}

DynamicDataSource.class
动态数据源类

public class DynamicDataSource extends AbstractRoutingDataSource {    @Override    protected Object determineCurrentLookupKey() {        String dataSource =DynamicDataSourceHolder.getDataSourceType();        return dataSource;    }}

DynamicDataSourceHolder.class
获得和设置上下文环境的类,主要负责改变上下文数据源的名称

public class DynamicDataSourceHolder {    private static final ThreadLocal<String> contextHolder= new ThreadLocal<String>();    public static void setDataSourceType(String dataSourceType) {        contextHolder.set(dataSourceType);    }    public static String getDataSourceType() {        return contextHolder.get();    }    public static void clearDataSourceType() {        contextHolder.remove();    }}

使用方法:

在你的service层事务开始的地方,即事务开始之前,使用如下代码切换数据源:

@DataSource(name= DataSourceAspect.dataSource_oracle)

这样就可以实现数据源切换了

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 王森学校学费多少 王森学校好吗 王森蛋糕技能培训学校 王森蛋糕学校学费 王森个人资料 王森蛋糕学校学费多少 王森学校怎么样 王森蛋糕培训 王森培训学校怎么样 王森蛋糕烘焙学校 王森培训学校 王森学校学费 王森艺术西点蛋糕学校 王森蛋糕培训学校学费多少 王森技术学校 王森艺术西点学校 王森学校在哪里 王森国际西点学校 王森糕点学校 王森糕点培训学校 我们约会吧 王森 王森咖啡培训学校 王森蛋糕学校地址 王森烘焙西点西餐咖啡学院 王森烘焙西点 王森蛋糕培训班 王森蛋糕培训学校好吗 王森咖啡学校 王森翻糖蛋糕培训 参差咖啡王森 王森咖啡西点学校 王森蛋糕装饰 王森蛋糕培训学校在哪里 王森面包书籍 王森生日蛋糕 王森蛋糕书籍 王森蛋糕裱花基础 王森蛋糕制作 王森蛋糕裱花 王森蛋糕图片 参差咖啡 王森