在applicationContent.xml中:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:config/jdbc.properties</value>
<value>classpath:config/cpool.properties</value>
</list>
</property>
</bean>
<!-- 主数据源 -->
<bean id="masterDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.masterDriverClass}" />
<property name="jdbcUrl" value="${jdbc.masterUrl}" />
<property name="user" value="${jdbc.masterUsername}" />
<property name="password" value="${jdbc.masterPassword}" />
<property name="checkoutTimeout" value="${cpool.checkoutTimeout}" />
<property name="initialPoolSize" value="${cpool.initialPoolSize}" />
<property name="minPoolSize" value="${cpool.minPoolSize}" />
<property name="maxPoolSize" value="${cpool.maxPoolSize}" />
<property name="maxIdleTime" value="${cpool.maxIdleTime}" />
<property name="acquireIncrement" value="${cpool.acquireIncrement}" />
<property name="maxIdleTimeExcessConnections" value="${cpool.maxIdleTimeExcessConnections}" />
</bean>
<!-- 从数据源 -->
<bean id="slaveDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.slaveDriverClass}" />
<property name="jdbcUrl" value="${jdbc.slaveUrl}" />
<property name="user" value="${jdbc.slaveUsername}" />
<property name="password" value="${jdbc.slavePassword}" />
<property name="checkoutTimeout" value="${cpool.checkoutTimeout}" />
<property name="initialPoolSize" value="${cpool.initialPoolSize}" />
<property name="minPoolSize" value="${cpool.minPoolSize}" />
<property name="maxPoolSize" value="${cpool.maxPoolSize}" />
<property name="maxIdleTime" value="${cpool.maxIdleTime}" />
<property name="acquireIncrement" value="${cpool.acquireIncrement}" />
<property name="maxIdleTimeExcessConnections" value="${cpool.maxIdleTimeExcessConnections}" />
</bean>
<!-- 动态切换数据源 -->
<bean id="dataSource" class="com.xxx.xxx.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="slave" value-ref="slaveDataSource" />
<entry key="master" value-ref="masterDataSource" />
</map>
</property>
<property name="defaultTargetDataSource" ref="masterDataSource" />
</bean>
<!-- 配置事务的传播特性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="update*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="*" read-only="true" propagation="SUPPORTS" />
</tx:attributes>
</tx:advice>
<!-- 动态切换数据源的切面 -->
<bean id="dataSourceAdvice" class="com.xxx.xxx.DataSourceAdvice" />
<!-- 那些类的哪些方法参与事务 -->
<aop:config>
<aop:pointcut id="txPointcut" expression="execution(* *..service*..*(..))" />
<aop:advisor order="-2147483648" pointcut-ref="txPointcut" advice-ref="dataSourceAdvice" /> <!-- 数据源主从切换(顺序要在事务上面) -->
<aop:advisor pointcut-ref="txPointcut" advice-ref="txAdvice" /><!-- 事务 -->
</aop:config>
Java类:
/** 数据源动态切换类 */
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceSwitcher.getDataSource();
}
}
/** 数据源转换器 */
public class DataSourceSwitcher {
private static final ThreadLocal contextHolder = new ThreadLocal();
@SuppressWarnings("unchecked")
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
public static void setMaster() {
setDataSource("master");
}
public static void setSlave() {
setDataSource("slave");
}
public static String getDataSource() {
return (String) contextHolder.get();
}
}
/** 数据源判断切面 */
public class DataSourceAdvice implements MethodBeforeAdvice, ThrowsAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable {
if (method.getName().startsWith("add") || method.getName().startsWith("create") || method.getName().startsWith("save") || method.getName().startsWith("edit") || method.getName().startsWith("update") || method.getName().startsWith("delete") || method.getName().startsWith("remove")) {
DataSourceSwitcher.setMaster();
} else {
DataSourceSwitcher.setSlave();
}
}
public void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable {
System.out.println("异常切换到: master");
DataSourceSwitcher.setMaster();
}
}
分享到:
相关推荐
通过简单的demo实现SpingBoot多数据源配置并动态切换多数据源
使用注解配置实现Spring动态数据源切换,实现原理 1、自定义动态数据源类DynamicDataSource: 实现spring类AbstractRoutingDataSource的方法determineCurrentLookupKey 2、自定义Spring AOP类DataSourceAspect 3、...
1. 基于Aspectj实现动态数据源切换,支持类级、方法级,方法级优先于类级 2. 实现数据源动态注册、修改、删除,无需重启服务 3. 实现同时兼容多种数据源连接池 4. 实现动态数据源连接池属性配置 5. 采用双端队列实现...
基于注解的Spring多数据源配置和使用 前一段时间研究了一下spring多数据源的配置和使用,...后来发现其实基于spring来配置和使用多数据源还是比较简单的,因为spring框架已经预留了这样的接口可以方便数据源的切换。
mybatis+spring实现动态切换数据源,修改数据源配置信息之后,直接运行test可进行测试
用于详细描述配置spring下多数据源动态切换方案的实施配置说明。可以自动切换数据源的配置。
请自行修改com/resources/datasource.properties中数据库配置,Demo中配置的两个数据源,一个是Mysql,一个是Oracle。 运行之前请自行建立数据库的表。
spring-boot集成mybatis+druid实现 hive/mysql多数据源切换,用mysql数据库作为用户验证库以及用户信息库,hive作为数据可视化源库。
Springcloud 多数库 多数据源整合,查询动态切换数据库
通过注解实现数据源的灵活切换
通过SpringAop实现多数据源的动态切换 并采用Druid连接池,可扩展继续增加数据库配置。
首先,这个方案完全是在spring的框架下解决的,数据源依然配置在spring的配置文件中,sessionFactory依然去配置它的dataSource属性,它甚至都不知道dataSource的改变。 其次,实现简单,易于维护。这个方案虽然我说...
mybatis+spring实现动态切换数据源,修改数据源配置信息之后,直接运行test可进行测试 maven项目 导入即可 jar包都不用 适合学习参考 出自Java自学网 (Java自学网专供 就是免积分下载)
1.配置数据源,2.动态数据源切换,3.注册动态数据源,4.动态数据源注解切点,5.通过切点切换数据源,6.在service层通过注解切换不同数据源,7.启动项目
用springboot 集成mybatis多数据源,用aop实现的动态切换,支持事务,不会使aop动态切换失效。注意:此代码不涉及分布式事务,如果需要分布式事务 需要采取其他方案。
项目中我们经常会遇到多数据源的问题,尤其是数据同步或定时任务等项目更是如此。多数据源让人最头痛的,不是配置多个数据源,而是如何能灵活动态的切换数据源。 spring多数据源 动态 创建 切换使用
本篇文章主要介绍了Spring配置多个数据源并实现动态切换示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
Spring 动态切换 数据源 可同事在多个数据源中切换
基于spring boot mybatis的多数据源配置,使用Druid配置连接池,使用注解自动切换数据源,完美运行!
SpringBoot+Mybatis配合AOP和注解实现动态数据源切换配置