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
相关推荐
在方法执行前,根据注解的值动态设置AbstractRoutingDataSource的数据源标识,从而完成数据源的切换。 5. 实现MybatisPlus的配置,使其能够识别并适配动态数据源。确保在多数据源环境下,每个数据源的...
Spring Boot简化了传统Spring应用的配置,通过`@EnableAutoConfiguration`注解,它能自动识别并配置相应的bean。在多数据源场景下,我们需要自定义数据源配置。 1. **集成Druid连接池** Druid是一个强大的Java...
通过以上步骤,我们成功实现了Spring Boot + MyBatis的多数据源配置,利用注解实现数据源的自动切换,以及简单的读写分离和负载均衡。这不仅可以提高系统的扩展性和可用性,还为后续的微服务架构打下了坚实的基础。...
Spring Boot会自动识别这些配置并管理数据源。 ```java @Configuration public class DataSourceConfig { @Bean(name = "primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.primary") ...
对于多数据源,我们需要为每个数据源创建一个@Bean,并通过@Primary注解或者在AOP中动态指定来区分主数据源和从数据源。 现在,让我们详细说明上述概念是如何在给定的文件中实现的。 - **依赖引入**:在实现多数据...
本教程将探讨如何通过自定义注解以及Spring Boot AOP(面向切面编程)来实现数据源之间的自动切换,同时整合Druid监控和MyBatis-Plus作为持久层框架。 首先,我们了解核心概念: 1. **多数据源**:在大型系统中,...
SSH动态切换数据源是一种在Java Web开发中处理多数据库连接切换的技术,主要应用于Spring、Struts和Hibernate(SSH)这三大框架集成的项目。SSH框架是企业级应用开发的常用组合,提供了强大的业务逻辑处理和数据持久...
比如,我们可以通过`@Primary`或自定义注解来标记方法选择主数据源,其他则默认使用次数据源: ```java @Aspect @Component public class DataSourceAspect { @Autowired @Qualifier("primaryDataSource") ...
5. **Mapper配置**:在MyBatis的映射器接口中,无需更改任何代码,因为MyBatis会根据配置好的数据源自动选择正确的数据库进行操作。 6. **事务管理**:在使用动态数据源时,需要注意事务管理。Spring的`...
3. **配置主数据源**: 在SpringBoot的配置类中,设置`DynamicDataSource`为主数据源,并注入所有配置的数据源。 ```java @Configuration public class DataSourceConfig { @Autowired private DynamicDataSource...
这里`DatasourceAnnotation`是你自定义的一个注解,用来标记需要切换数据源的方法。在方法执行前后,通过`DataSourceContextHolder`改变当前线程绑定的数据源。 同时,你需要一个`DataSourceContextHolder`类来保存...
Spring框架提供了强大的支持,允许我们通过注解轻松地进行数据源的切换和管理,从而实现灵活的数据操作。本篇文章将深入探讨如何基于注解和Spring实现多数据源配置和使用。 首先,我们需要理解"注解"在Java中的作用...
使用注解配置实现Spring动态数据源切换,实现原理 1、自定义动态数据源类DynamicDataSource: 实现spring类AbstractRoutingDataSource的方法determineCurrentLookupKey 2、自定义Spring AOP类DataSourceAspect 3、...
- 利用`@Profile`注解:为每个数据源创建不同的配置类,通过激活特定的profile来切换数据源。 5. **项目结构分析** - `dynamicDataSource`目录可能包含以下关键组件: - `application.properties`或`application...
接下来,使用`@ConfigurationProperties`注解将这些配置注入到Java配置类中,并通过`@Primary`标记主数据源: ```java @Configuration @ConfigurationProperties(prefix = "spring.datasource.primary") public ...
在测试方法中,我们可以先切换到一个数据源执行查询,然后切换到另一个数据源执行其他操作。 ```java @Test public void testDynamicSwitch() { // 切换数据源 DataSourceContextHolder.setDataSource(...
这里的【标题】"读写数据源通过事务注解进行读写切换"正是描述了这种策略的一种实现方式。【描述】中提到,通过拦截器检查方法上的事务注解来决定使用读库还是写库,这确保了业务逻辑的清晰性和可维护性。下面将详细...
4. **动态数据源切换**:对于MyBatis,可以在SqlSessionTemplate中设置数据源,或者使用`@MapperScan`注解配合自定义数据源路由类来实现。 **六、实战项目分析** 在`springboot-multi-datasource-master`项目中,...
- **声明式切换**:通过AOP切面或者自定义注解,可以在方法执行前切换数据源。例如,可以创建一个`@SwitchDataSource`注解,定义目标数据源,然后编写切面逻辑来处理这个注解,改变`AbstractRoutingDataSource`的...