`
y806839048
  • 浏览: 1108180 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

通过识别方法注解,自动切换主备数据源DynamicDataSource

    博客分类:
  • data
阅读更多

 

 

org.springframework.jdbc.datasource.lookup,数据库主备配置

 

mysql.properties:

 

crm.jdbc.driverClassName=com.mysql.jdbc.Driver 

crm.jdbc.url=jdbc:mysql://10.100.163.77:3306/financial_sales_prod?useUnicode=true&characterEncoding=utf-8

crm.jdbc.username=telsale/-pl

crm.jdbc.password=0OKM

crm.dbcp.initialSize=5

crm.dbcp.minIdle=5

crm.dbcp.maxActive=20

crm.dbcp.maxWait=10000

crm.dbcp.timeBetweenEvictionRunsMillis=60000

crm.dbcp.minEvictableIdleTimeMillis=300000

crm.dbcp.testWhileIdle=true

crm.dbcp.testOnBorrow=true

crm.dbcp.testOnReturn=false

crm.dbcp.poolPreparedStatements=true

crm.dbcp.maxPoolPreparedStatementPerConnectionSize=20

 

bigdata.jdbc.driverClassName=com.mysql.jdbc.Driver 

bigdata.jdbc.url=jdbc:mysql://10.100.163.78:3306/financial_sales_prod?useUnicode=true&characterEncoding=utf-8

bigdata.jdbc.username=telsale/-pl

bigdata.jdbc.password=0OKM

bigdata.dbcp.initialSize=5

bigdata.dbcp.minIdle=5

bigdata.dbcp.maxActive=20

bigdata.dbcp.maxWait=10000

bigdata.dbcp.timeBetweenEvictionRunsMillis=60000

bigdata.dbcp.minEvictableIdleTimeMillis=300000

bigdata.dbcp.testWhileIdle=true

bigdata.dbcp.testOnBorrow=true

bigdata.dbcp.testOnReturn=false

bigdata.dbcp.poolPreparedStatements=true

bigdata.dbcp.maxPoolPreparedStatementPerConnectionSize=20

 

 

 

 

 

 

 

 

applicationContext-dao.xml:

 

 

 

 

 

<?xml version="1.0" encoding="UTF-8"?>

 

<!--suppress ALL -->

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:context="http://www.springframework.org/schema/context"

       xmlns:tx="http://www.springframework.org/schema/tx"

       xmlns:aop="http://www.springframework.org/schema/aop"

       xmlns="http://www.springframework.org/schema/beans"

       xsi:schemaLocation="

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

 

    <bean id="crm_dataSource" class="com.alibaba.druid.pool.DruidDataSource"

          init-method="init" destroy-method="close">

        <property name="driverClassName" value="${crm.jdbc.driverClassName}"/>

        <property name="url" value="${crm.jdbc.url}"/>

        <property name="username" value="${crm.jdbc.username}"/>

        <property name="password" value="${crm.jdbc.password}"/>

 

        <!-- 配置初始化大小、最小、最大 -->

        <property name="initialSize" value="${crm.dbcp.initialSize}"/>

        <property name="minIdle" value="${crm.dbcp.minIdle}"/>

        <property name="maxActive" value="${crm.dbcp.maxActive}"/>

 

        <!-- 配置获取连接等待超时的时间 -->

        <property name="maxWait" value="${crm.dbcp.maxWait}"/>

 

        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->

        <property name="timeBetweenEvictionRunsMillis" value="${crm.dbcp.timeBetweenEvictionRunsMillis}"/>

 

        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->

        <property name="minEvictableIdleTimeMillis" value="${crm.dbcp.minEvictableIdleTimeMillis}"/>

 

        <property name="testWhileIdle" value="${crm.dbcp.testWhileIdle}"/>

 

        <!-- 防止取到的连接不可用, 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能-->

        <property name="testOnBorrow" value="${crm.dbcp.testOnBorrow}"/>

        <!-- 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 -->

        <property name="testOnReturn" value="${crm.dbcp.testOnReturn}"/>

 

        <!-- 打开PSCache,并且指定每个连接上PSCache的大小 在mysql5.5以下的版本中没有PSCache功能,建议关闭掉。5.5及以上版本有PSCache,建议开启-->

        <property name="poolPreparedStatements" value="${crm.dbcp.poolPreparedStatements}"/>

        <property name="maxPoolPreparedStatementPerConnectionSize"

                  value="${crm.dbcp.maxPoolPreparedStatementPerConnectionSize}"/>

 

        <!-- 这里配置提交方式,默认就是TRUE,可以不用配置 -->

        <property name="defaultAutoCommit" value="true"/>

 

        <!-- 验证连接有效与否的SQL,不同的数据库配置不同 -->

        <property name="validationQuery" value="select 1 "/>

        <!-- 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:监控统计用的filter:stat 日志用的filter:log4j 防御sql注入的filter:wall-->

        <property name="filters" value="stat"/>

       <!--  <property name="proxyFilters">

            <list>

                <ref bean="logFilter"/>

            </list>

        </property> -->

    </bean>

 

    <bean id="bigdata_dataSource" class="com.alibaba.druid.pool.DruidDataSource"

          init-method="init" destroy-method="close">

        <property name="driverClassName" value="${bigdata.jdbc.driverClassName}"/>

        <property name="url" value="${bigdata.jdbc.url}"/>

        <property name="username" value="${bigdata.jdbc.username}"/>

        <property name="password" value="${bigdata.jdbc.password}"/>

 

        <!-- 配置初始化大小、最小、最大 -->

        <property name="initialSize" value="${bigdata.dbcp.initialSize}"/>

        <property name="minIdle" value="${bigdata.dbcp.minIdle}"/>

        <property name="maxActive" value="${bigdata.dbcp.maxActive}"/>

 

        <!-- 配置获取连接等待超时的时间 -->

        <property name="maxWait" value="${bigdata.dbcp.maxWait}"/>

 

        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->

        <property name="timeBetweenEvictionRunsMillis" value="${bigdata.dbcp.timeBetweenEvictionRunsMillis}"/>

 

        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->

        <property name="minEvictableIdleTimeMillis" value="${bigdata.dbcp.minEvictableIdleTimeMillis}"/>

 

        <property name="testWhileIdle" value="${bigdata.dbcp.testWhileIdle}"/>

 

        <!-- 防止取到的连接不可用, 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能-->

        <property name="testOnBorrow" value="${bigdata.dbcp.testOnBorrow}"/>

        <!-- 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 -->

        <property name="testOnReturn" value="${bigdata.dbcp.testOnReturn}"/>

 

        <!-- 打开PSCache,并且指定每个连接上PSCache的大小 在mysql5.5以下的版本中没有PSCache功能,建议关闭掉。5.5及以上版本有PSCache,建议开启-->

        <property name="poolPreparedStatements" value="${bigdata.dbcp.poolPreparedStatements}"/>

        <property name="maxPoolPreparedStatementPerConnectionSize"

                  value="${bigdata.dbcp.maxPoolPreparedStatementPerConnectionSize}"/>

 

        <!-- 这里配置提交方式,默认就是TRUE,可以不用配置 -->

        <property name="defaultAutoCommit" value="true"/>

 

        <!-- 验证连接有效与否的SQL,不同的数据库配置不同 -->

        <property name="validationQuery" value="select 1 "/>

        <!-- 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:监控统计用的filter:stat 日志用的filter:log4j 防御sql注入的filter:wall-->

        <property name="filters" value="stat"/>

        <property name="proxyFilters">

            <list>

                <ref bean="logFilter"/>

            </list>

        </property>

    </bean>

 

    <bean id="logFilter" class="com.alibaba.druid.filter.logging.Slf4jLogFilter">

        <property name="statementExecutableSqlLogEnable" value="false"/>

        <property name="resultSetLogEnabled" value="false"/>

        

        

    </bean>

 

    <bean id="dynamicDataSource"  class="com.houbank.incoming.dao.datasource.DynamicDataSource" >

        <property name="targetDataSources" >

            <map>

                <entry key="crm_dataSource" value-ref="crm_dataSource" />    //两个数据源

                <entry key="bigdata_dataSource" value-ref="bigdata_dataSource" />

            </map>

        </property>

        <property name="defaultTargetDataSource"  ref="crm_dataSource" />  //主库

    </bean>

 

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

        <property name="dataSource" ref="dynamicDataSource"/>

        <property name="mapperLocations">

            <array>

                <value>classpath*:mapper/*.xml</value>

                <value>classpath*:WorkProcessorMapper/*.xml</value>

            </array>

        </property>

        <property name="configLocation" value="classpath:/META-INF/spring/mybatis-configuration.xml"/>

    </bean>

 

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

        <property name="basePackage" value="com.houbank.incoming.dao.mapper"/>

        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>

    </bean>

 

   

 

    <!--动态数据源切面配置-->

    <bean id="dataSourceAspect" class="com.houbank.incoming.dao.datasource.DynamicDataSourceAspect" />  //切面配置

 

    <!-- 事务配置开始 -->

    <bean id="transactionManager"

          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

        <property name="dataSource" ref="dynamicDataSource"/>

    </bean>

    <tx:annotation-driven/>

    <!--对于方法的细粒度事务配置,符合条件的方法冠以相应的事务-->

    <tx:advice id="txAdvice" transaction-manager="transactionManager">

        <tx:attributes>

            <tx:method name="delete*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>

            <tx:method name="remove*" 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="add*" 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="submit*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>

            <tx:method name="newTrans*" propagation="REQUIRES_NEW" read-only="false"

                       rollback-for="java.lang.Exception"/>

            <tx:method name="modify*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>

            <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>

            <tx:method name="get*" propagation="SUPPORTS" read-only="true"/>

            <tx:method name="select*" propagation="SUPPORTS" read-only="true"/>

            <tx:method name="query*" propagation="SUPPORTS" read-only="true"/>

        </tx:attributes>

    </tx:advice>

    <!--把事务控制在Service层 -->

    <aop:config>

        <!--这里配置规则,满足以下规则的将触发事务,第一个*表示所有返回类型,第二个表示service包下的所有class,第三个表示所有方法-->

        <aop:pointcut id="servicePointCut"

                      expression="execution(public * com.houbank.incoming.service.*.*(..))"/>

        <aop:advisor pointcut-ref="servicePointCut" advice-ref="txAdvice"/>

        <!-- 将切面应用到自定义的切面处理器上,-9999保证该切面优先级最高执行 -->

        <aop:advisor advice-ref="dataSourceAspect" pointcut-ref="servicePointCut" order="1" />

    </aop:config>

    <!-- 事务配置结束 -->

</beans>

 

 

 

 

 

 

 

java:

 

 

自定义数据源:

 

package com.houbank.incoming.dao.datasource;

 

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

 

import javax.sql.DataSource;

 

/**

 * Created by xiaogaoxu on 2016/8/25.

 */

public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override

    protected Object determineCurrentLookupKey() {

        return DatasourceHold.getDBType();

    }

 

    @Override

    public DataSource determineTargetDataSource() {

        return super.determineTargetDataSource();

    }

}

 

 

 

自定义数据源切面:

 

package com.houbank.incoming.dao.datasource;

 

import java.lang.reflect.Method;

 

import org.springframework.aop.AfterReturningAdvice;

import org.springframework.aop.MethodBeforeAdvice;

 

/**

 * Created by xiaogaoxu on 2016/8/25.

 */

public class DynamicDataSourceAspect implements MethodBeforeAdvice, AfterReturningAdvice {

 

    @Override

    public void afterReturning(Object returnValue, Method method,

                               Object[] args, Object target) throws Throwable {

        DatasourceHold.clearDBType();

    }

 

    @Override

    public void before(Method method, Object[] args, Object target)

            throws Throwable {

 

        if (method.isAnnotationPresent(DataSource.class)) {     //这里通过方法的注解区分哪些方式使用哪种数据库,大数据查询的专门使用查询的库

            DataSource datasource = method.getAnnotation(DataSource.class);

            DatasourceHold.setDBType(datasource.name());

        } else {

            DatasourceHold.clearDBType();

        }

 

    }

}

 

 

 

 

 

package com.houbank.incoming.dao.datasource;

 

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

 

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface DataSource {

    /**

     * CRM系统的主数据源 系统默认

     */

    String CRM_DATASOURCE = "crm_dataSource";

 

    /**

     * 大数据的数据源 只读同步数据

     */

    String BIGDATA_DATASOURCE = "bigdata_dataSource";

 

    String name();

}

 

 

 mybatis采用的是多数据源配置

crm_dataSource CRM系统的主数据源
bigdata_dataSource 大数据的数据源 只读同步数据

示例:
@DataSource(name = DataSource.BIGDATA_DATASOURCE)
   public List<TagFilterRel> selectByCondition(TagFilterRel rel) {
           return tagFilterRelMapper.selectByCondition(rel);
       }

mybatis数据源及事务配置见applicationContext-dao.xml
分享到:
评论

相关推荐

    Spring+SpringMvc+MybatisPlus+Aop(自定义注解)动态切换数据源

    在方法执行前,根据注解的值动态设置AbstractRoutingDataSource的数据源标识,从而完成数据源的切换。 5. 实现MybatisPlus的配置,使其能够识别并适配动态数据源。确保在多数据源环境下,每个数据源的...

    spring boot多数据源(AOP注解动态切换)

    Spring Boot简化了传统Spring应用的配置,通过`@EnableAutoConfiguration`注解,它能自动识别并配置相应的bean。在多数据源场景下,我们需要自定义数据源配置。 1. **集成Druid连接池** Druid是一个强大的Java...

    springboot+mybatis配置多数据源,通过注解自动切换

    通过以上步骤,我们成功实现了Spring Boot + MyBatis的多数据源配置,利用注解实现数据源的自动切换,以及简单的读写分离和负载均衡。这不仅可以提高系统的扩展性和可用性,还为后续的微服务架构打下了坚实的基础。...

    对应的文章 Springboot Mybatis 多数据源利用注解动态切换数据库

    Spring Boot会自动识别这些配置并管理数据源。 ```java @Configuration public class DataSourceConfig { @Bean(name = "primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.primary") ...

    spring-boot自定注解,实现多个数据源之间的自动切换

    本教程将探讨如何通过自定义注解以及Spring Boot AOP(面向切面编程)来实现数据源之间的自动切换,同时整合Druid监控和MyBatis-Plus作为持久层框架。 首先,我们了解核心概念: 1. **多数据源**:在大型系统中,...

    SSH动态切换数据源

    SSH动态切换数据源是一种在Java Web开发中处理多数据库连接切换的技术,主要应用于Spring、Struts和Hibernate(SSH)这三大框架集成的项目。SSH框架是企业级应用开发的常用组合,提供了强大的业务逻辑处理和数据持久...

    springboot配置多数据源,注解自由切换,完美运行

    比如,我们可以通过`@Primary`或自定义注解来标记方法选择主数据源,其他则默认使用次数据源: ```java @Aspect @Component public class DataSourceAspect { @Autowired @Qualifier("primaryDataSource") ...

    ssm动态切换数据源

    5. **Mapper配置**:在MyBatis的映射器接口中,无需更改任何代码,因为MyBatis会根据配置好的数据源自动选择正确的数据库进行操作。 6. **事务管理**:在使用动态数据源时,需要注意事务管理。Spring的`...

    根据用户动态切换数据源java代码 dynamicds

    3. **配置主数据源**: 在SpringBoot的配置类中,设置`DynamicDataSource`为主数据源,并注入所有配置的数据源。 ```java @Configuration public class DataSourceConfig { @Autowired private DynamicDataSource...

    springboot-AOP实现多数据源动态切换(Druid连接池)

    对于多数据源,我们需要为每个数据源创建一个@Bean,并通过@Primary注解或者在AOP中动态指定来区分主数据源和从数据源。 现在,让我们详细说明上述概念是如何在给定的文件中实现的。 - **依赖引入**:在实现多数据...

    SpringBoot配置多数据源实现动态切换数据源

    这里`DatasourceAnnotation`是你自定义的一个注解,用来标记需要切换数据源的方法。在方法执行前后,通过`DataSourceContextHolder`改变当前线程绑定的数据源。 同时,你需要一个`DataSourceContextHolder`类来保存...

    基于注解和Spring的多数据源配置和使用

    Spring框架提供了强大的支持,允许我们通过注解轻松地进行数据源的切换和管理,从而实现灵活的数据操作。本篇文章将深入探讨如何基于注解和Spring实现多数据源配置和使用。 首先,我们需要理解"注解"在Java中的作用...

    使用注解配置实现Spring动态数据源切换

    使用注解配置实现Spring动态数据源切换,实现原理 1、自定义动态数据源类DynamicDataSource: 实现spring类AbstractRoutingDataSource的方法determineCurrentLookupKey 2、自定义Spring AOP类DataSourceAspect 3、...

    spring boot动态切换多数据源

    - 利用`@Profile`注解:为每个数据源创建不同的配置类,通过激活特定的profile来切换数据源。 5. **项目结构分析** - `dynamicDataSource`目录可能包含以下关键组件: - `application.properties`或`application...

    使用springboot + JPA / MyBatis 实现多数据源动态切换

    4. **动态数据源切换**:对于MyBatis,可以在SqlSessionTemplate中设置数据源,或者使用`@MapperScan`注解配合自定义数据源路由类来实现。 **六、实战项目分析** 在`springboot-multi-datasource-master`项目中,...

    springboot实现多数据源而且加上事务不会使aop切换数据源失效

    接下来,使用`@ConfigurationProperties`注解将这些配置注入到Java配置类中,并通过`@Primary`标记主数据源: ```java @Configuration @ConfigurationProperties(prefix = "spring.datasource.primary") public ...

    mybatis+spring实现动态切换数据源

    在测试方法中,我们可以先切换到一个数据源执行查询,然后切换到另一个数据源执行其他操作。 ```java @Test public void testDynamicSwitch() { // 切换数据源 DataSourceContextHolder.setDataSource(...

    读写数据源通过事物注解进行读写切换

    这里的【标题】"读写数据源通过事务注解进行读写切换"正是描述了这种策略的一种实现方式。【描述】中提到,通过拦截器检查方法上的事务注解来决定使用读库还是写库,这确保了业务逻辑的清晰性和可维护性。下面将详细...

    Spring Boot多数据源(支持Spring声明式事务切换和回滚).pdf

    - 通过AspectJ实现数据源的动态切换,可以设置在类级别或方法级别,方法级的设置优先于类级。这使得开发者可以根据业务逻辑自由地决定使用哪个数据源。 - 数据源的注册、修改和删除可以在运行时完成,无需重启服务...

Global site tag (gtag.js) - Google Analytics