« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
| 公告 |
戒除浮躁,读好书,交益友 |
Blog信息 |
blog名称:邢红瑞的blog 日志总数:523 评论数量:1142 留言数量:0 访问次数:9694720 建立时间:2004年12月20日 |

| |
[j2ee]spring2多数据源的使用 原创空间, 软件技术, 电脑与网络
邢红瑞 发表于 2006/6/19 16:33:48 |
在实际的项目中,一般很少使用一个数据库,出于灾难恢复或者负载均衡考虑,生产环境中会存在多台数据库服务器,在应用程序对这些数据库进行数据访问的时候, 如何管理数据访问过程中的多个数据源。Spring2.0.1以后的版本已经支持配置多数据源,并且可以在运行的时候动态加载不同的数据源。通过继承AbstractRoutingDataSource就可以实现多数据源的动态转换。 一般使用ThreadLocal类存储key值。 Java代码 public class CustomerContextHolder { private static final ThreadLocal contextHolder = new ThreadLocal(); public static void setCustomerType(String customerType) { contextHolder.set(customerType); } public static String getCustomerType() { return (String) contextHolder.get(); } public static void clearCustomerType() { contextHolder.remove(); } }
这个主要负责设置上下文环境和获得上下文环境。 建立动态数据源类,这个类继承spring的AbstractRoutingDataSource: Java代码 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource { protected Object determineCurrentLookupKey() { return CustomerContextHolder.getCustomerType(); } }
主要是实现determineCurrentLookupKey方法,配置文件
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:jdbc.properties" /> </bean> <bean id="parentDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="maxActive" value="80" /> <property name="maxIdle" value="10" /> <property name="maxWait" value="10000" /> </bean>
<bean id="dataSource0" parent="parentDataSource"> <property name="url" value="${jdbc.url1}" /> <property name="username" value="${jdbc.username1}" /> <property name="password" value="${jdbc.password1}" /> </bean>
<bean id="dataSource1" parent="parentDataSource"> <property name="url" value="${jdbc.url2}" /> <property name="username" value="${jdbc.username2}" /> <property name="password" value="${jdbc.password2}" /> </bean>
spring配置文件配置多数据源映射关系 Java代码 <bean id="dataSource" class="com.tatan.DynamicDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry key="auk" value-ref="dataSource1"/> </map> </property> <property name="defaultTargetDataSource" ref="dataSource0"/> </bean> targetDataSources 需要的注入的是map类型的值。
使用前先设置 CustomerContextHolder.setCustomerType("auk");一般来说动态切换用于实现负载均衡,使用相同的数据库是最好的选择,只要我们有效地实现数据库间同步,就可以有效减少单个数据库的负载。假设我们有三台数据库用来实现负载均衡,所有的数据访问请求最终需要平均的分配到这三台数据库服务器之上。public class LoadBalanceDataSource extends AbstractRoutingDataSource {
private Lock lock = new ReentrantLock(); private int counter = 0; private int dataSourceNumber = 3;
@Override protected Object determineCurrentLookupKey() { lock.lock(); try { counter++; int lookupKey = counter % getDataSourceNumber(); return new Integer(lookupKey); } finally { lock.unlock(); } } // ...}一般不能用于不同数据库之间的切换,因为hibernate无法实现配置一个sessionfactory,hibernate.dialect解析无法做到。本文的代码和思路,没有用于启明星辰的任何产品,包括UTM。 |
|
|