动态切换数据源确切的来说是在同一类型数据库的情况下的。意思就是说 , 在系统中的使用的数据库分布在多台数据库服务器或者在同台服务器上的多个数据库. 在运行时期间根据某种标识符来动态的选择当前操作的数据库.
- 数据源是相同类型的数据库: 一个SessionFactory+动态数据源+一个事务管理器
- 数据源是不同类型的数据库: 根据类型 配置多套SessionFactory
spring配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<!-- 如果还有其他的发放类型需要进行事务的统一处理,请修改此处的key值和事务等级 -->
<props>
<prop key="insert*">PROPAGATION_REQUIRES_NEW</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="upadate*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="import*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="cancel*">PROPAGATION_REQUIRED</prop>
<prop key="create*">PROPAGATION_REQUIRED</prop>
<prop key="download*">PROPAGATION_REQUIRED</prop>
<prop key="upload*">PROPAGATION_REQUIRED</prop>
<prop key="doProcessor*">PROPAGATION_REQUIRED</prop>
<prop key="approve*">PROPAGATION_REQUIRED</prop>
<prop key="doVerfy*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="list*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="query*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="search*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="is*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="has*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
<!-- DBCP数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<!-- 初始化个数 可修改数量 -->
<property name="initialSize" value="${initialSize}" />
<!-- 最大连接数据库连接数,设置为0时,表示没有限制 可修改数量 -->
<property name="maxActive" value="${maxActive}" />
<!-- 最大等待秒数,单位为毫秒, 超过时间会报出错误信息 -->
<property name="maxWait" value="1" />
<!-- 最大等待连接中的数量,设置为0时,表示没有限制 -->
<property name="maxIdle" value="1" />
<!-- 是否自我中断,默认是 false -->
<property name="removeAbandoned" value="true" />
<!-- 几秒后数据连接会自动断开,在removeAbandoned为true,提供该值 -->
<property name="removeAbandonedTimeout" value="150" />
<!-- 是否记录中断事件, 默认为 false -->
<property name="logAbandoned" value="true" />
</bean>
<!-- DBCP数据源 -->
<bean id="dataSourceTwo" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${dbTwo.driverClassName}" />
<property name="url" value="${dbTwo.url}" />
<property name="username" value="${dbTwo.username}" />
<property name="password" value="${dbTwo.password}" />
<!-- 初始化个数 可修改数量 -->
<property name="initialSize" value="${dbTwo.initialSize}" />
<!-- 最大连接数据库连接数,设置为0时,表示没有限制 可修改数量 -->
<property name="maxActive" value="${dbTwo.maxActive}" />
<!-- 最大等待秒数,单位为毫秒, 超过时间会报出错误信息 -->
<property name="maxWait" value="1" />
<!-- 最大等待连接中的数量,设置为0时,表示没有限制 -->
<property name="maxIdle" value="1" />
<!-- 是否自我中断,默认是 false -->
<property name="removeAbandoned" value="true" />
<!-- 几秒后数据连接会自动断开,在removeAbandoned为true,提供该值 -->
<property name="removeAbandonedTimeout" value="150" />
<!-- 是否记录中断事件, 默认为 false -->
<property name="logAbandoned" value="true" />
</bean>
<bean id="dynamicDataSource" class="com.siit.digital.framework.common.datasourceswitch.impl.DynamicDataSource" >
<!-- 通过key-value的形式来关联数据源 -->
<property name="targetDataSources">
<map>
<entry value-ref="dataSource" key="dataSource"></entry>
<entry value-ref="dataSourceTwo" key="dataSourceTwo"></entry>
</map>
</property>
<!-- 默认数据源 -->
<property name="defaultTargetDataSource" ref="dataSource" >
</property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dynamicDataSource" />
</property>
<property name="mappingLocations">
<list>
<value>classpath*:modelConfig/db1/${dataSource}/*.hbm.xml</value>
<value>classpath*:modelConfig/db2/${dbTwo.dataSource}/*.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
</beans>
properties配置
driverClassName=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@192.168.2.112:1521:ORCL
username=imssc5
password=sa
initialSize=5
maxActive=50
hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
dataSource=oracle
jndiName=image
dbTwo.driverClassName=com.mysql.cj.jdbc.Driver
dbTwo.url=jdbc\:mysql\://localhost\:3306/zgh?serverTimezone=GMT&autoReconnect=true&characterEncoding=utf-8&useSSL=false
dbTwo.username=root
dbTwo.password=gao24
dbTwo.initialSize=5
dbTwo.maxActive=50
dbTwo.dataSource=mysql
dbTwo.hibernate.dialect=org.hibernate.dialect.MySQLDialect
DynamicDataSource类
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
// 获取数据源标识
return DynamicDataSourceHolder.getDataSource();
}
}
DynamicDataSourceHolder类
public class DynamicDataSourceHolder {
// 线程本地环境
private static final ThreadLocal contextHolder = new ThreadLocal();
// 设置数据源类型
public static void setDataSourceType(String dataSourceType) {
contextHolder.set(dataSourceType);
}
// 获取数据源类型
public static String getDataSourceType() {
return (String) contextHolder.get();
}
// 清除数据源类型
public static void clearDataSourceType() {
contextHolder.remove();
}
}
切换可以直接根据注册进动态数据源的key值进行选择。
需要注意的是,切换数据源要在事务之前就可以了。否则不生效。
@Controller
public class Test {
@Autowired
private DynDataSourceService dataSourceService;
@RequestMapping("/Test")
public String test() {
DynamicDataSourceHolder.setDataSource("dataSourceTwo");
return dataSourceService.find();
}
}
参考:

4852

被折叠的 条评论
为什么被折叠?



