多数据源配置:实现主(Master)从(Slave)库分离方式,减轻主库压力,从库负责查询。还有使用中需要用到两个数据库时候,使用多数据源配置,可以实现多库之间切换。
applicationContext.xml
<!-- 配置数据源 Master主-->
<bean id="dataSourceMaster" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"></property>
<property name="url" value="数据库地址"></property>
<property name="username" value="账户名"></property>
<property name="password" value="密码"></property>
<property name="maxActive" value="20"/>
<property name="maxIdle" value="30"/>
<property name="initialSize" value="1"/>
<property name="maxWait" value="10000"/>
<property name="defaultAutoCommit" value="true"/>
<property name="removeAbandoned" value="true"/>
<property name="removeAbandonedTimeout" value="60"/>
<property name="logAbandoned" value="true"/>
</bean>
<!-- 配置数据源 Slave从库-->
<bean id="dataSourceSlave" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"></property>
<property name="url" value="数据库地址"></property>
<property name="username" value="帐号"></property>
<property name="password" value="密码"></property>
<property name="maxActive" value="20"/>
<property name="maxIdle" value="30"/>
<property name="initialSize" value="1"/>
<property name="maxWait" value="10000"/>
<property name="defaultAutoCommit" value="true"/>
<property name="removeAbandoned" value="true"/>
<property name="removeAbandonedTimeout" value="60"/>
<property name="logAbandoned" value="true"/>
</bean>
<!-- 数据源 切换 -->
<bean id="multipledataSource" class="com.xxx.mobile.datasource.MultipleDataSource"><!-- 注入数据源路由 -->
<property name="defaultTargetDataSource" ref="dataSourceMaster"/><!-- 默认数据源 -->
<property name="targetDataSources">
<map key-type="java.lang.String"><!-- 把主从数据库添加到map集合 -->
<entry key="master" value-ref="dataSourceMaster"/>
<entry key="slave" value-ref="dataSourceSlave"/>
</map>
</property>
</bean>
<!-- Aop 数据源 切换 -->
<bean id="dataSourceSwitchingAop" class="com.xxx.mobile.datasource.MultipleDataSourceAspectAdvice"/>
<!-- 配置aop -->
<aop:config>
<!-- 切换数据源的事务需要放到数据库事务开启前执行。针对上述代码示例中,配置aop时需要指定order(值越小,执行越靠前) -->
<aop:aspect id="dataSourceSwitching" ref="dataSourceSwitchingAop" order="0"><!-- 注入数据源路由 dataSourceSwitchingAop-->
<aop:pointcut id="dataSourceSwitchingService"
expression="execution(* com.xxx.mobile.mapper.*.*(..))"/>
<aop:before method="switchDataSource" pointcut-ref="dataSourceSwitchingService"/>
</aop:aspect>
</aop:config>
<!-- 配置Session工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="multipledataSource"></property><!-- 注入 数据源切换 id multipledataSource-->
<!-- 加载mybatis.cfg.xml文件 -->
<property name="configLocation" value="classpath:mybatis.cfg.xml"></property>
<!-- 自动扫描需要定义类别名的包,将包内的JAVA类的类名作为类别名 -->
<property name="typeAliasesPackage" value="com.infolink.trade.beans"></property>
</bean>
MultipleDataSource.java
/**
* 多数据源配置
* AbstractRoutingDataSource 数据源路由
* 实现其抽象方法determineCurrentLookupKey(),从而实现对不同数据源的路由功能
*/
public class MultipleDataSource extends AbstractRoutingDataSource{
//ThreadLocal 保证每个请求都会由一个线程来处理, 是分层系统中共享变量的 高级方式
private final static ThreadLocal<String> dataSourceKey = new ThreadLocal<String>();
public static void setDataSourceKey(String dataSource){
dataSourceKey.set(dataSource);
}
@Override
protected Object determineCurrentLookupKey() {
return dataSourceKey.get();
}
}
MultipleDataSourceAspectAdvice.java
/**
* AOP
* 数据源 转换
*/
@Component //自动扫描
public class MultipleDataSourceAspectAdvice {
public void switchDataSource(JoinPoint joinPoint){
Object object = joinPoint.getTarget();
DataSourceKey annotation = AnnotationUtils.findAnnotation(object.getClass(),DataSourceKey.class);
if(null!=annotation){//没有注解的用默认值
String value = annotation.value();
if(null!=value&&value.length()>0){
MultipleDataSource.setDataSourceKey(value);
}
}else{
MultipleDataSource.setDataSourceKey("master");
}
}
}
注:配置文件需要配置扫描 和 启动AOP支持
DataSourceKey.java
/**
* 自定义注解
* 在mapper包下类或方法上添加自定义注解@DataSourceKey(value="slave")
* 进而实现切换数据源到 slave
*/
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSourceKey {
String value() default "slave";
}
使用时候只需要在对应类或方法上添加注解,即可实现数据源切换
例:
@MapperScan
@DataSourceKey(value="slave") //切换数据源
public interface CardDao {}//类名
本文为博主第一次发文,学习使用过程中整理了一下,欢迎大神们多多提建议、讨论。