在很多大型應(yīng)用中都會對數(shù)據(jù)進(jìn)行切分,并且采用多個數(shù)據(jù)庫實例進(jìn)行管理,這樣可以有效提高系統(tǒng)的水平伸縮性。而這樣的方案就會不同于常見的單一數(shù)據(jù)實例的方案,這就要程序在運行時根據(jù)當(dāng)時的請求及系統(tǒng)狀態(tài)來動態(tài)的決定將數(shù)據(jù)存儲在哪個數(shù)據(jù)庫實例中,以及從哪個數(shù)據(jù)庫提取數(shù)據(jù)。
Figure 1 數(shù)據(jù)分割及多數(shù)據(jù)庫架構(gòu)
通常這種多數(shù)據(jù)源的邏輯會滲透到業(yè)務(wù)邏輯中,同時也會給我們使用的數(shù)據(jù)訪問API諸如Hibernate和iBatis等帶來不便(需要指定多個SessionFactory或SqlMapClient實例來對應(yīng)多個DataSource)。

Figure 2 多數(shù)據(jù)源的選擇邏輯滲透至客戶端
解決方案

Figure 3 采用Proxy模式來封裝數(shù)據(jù)源選擇邏輯
通過采用Proxy模式我們在方案中實現(xiàn)一個虛擬的數(shù)據(jù)源,并且用它來封裝數(shù)據(jù)源選擇邏輯,這樣就可以有效地將數(shù)據(jù)源選擇邏輯從Client中分離出來。
Client提供選擇所需的上下文(因為這是Client所知道的),由虛擬的DataSource根據(jù)Client提供的上下文來實現(xiàn)數(shù)據(jù)源的選擇。
Spring2.x的版本中提供了實現(xiàn)這種方式的基本框架,虛擬的DataSource僅需繼承AbstractRoutingDataSource實現(xiàn)determineCurrentLookupKey()在其中封裝數(shù)據(jù)源的選擇邏輯。
實例:
publicclass DynamicDataSource extends AbstractRoutingDataSource {
static Logger log = Logger.getLogger("DynamicDataSource");
@Override
protected Object determineCurrentLookupKey() {
String userId=(String)DbContextHolder.getContext();
Integer dataSourceId=getDataSourceIdByUserId(userId);
return dataSourceId;
}
}
實例中通過UserId來決定數(shù)據(jù)存放在哪個數(shù)據(jù)庫中。
配置文件示例:
<bean id="dataSource" class="com.bitfone.smartdm.datasource.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.Integer">
<entry key="0" value-ref="dataSource0"/>
<entry key="1" value-ref="dataSource1"/>
<entry key="2" value-ref="dataSource2"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource0"/>
</bean>
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:com/bitfone/smartdm/dao/sqlmap/sql-map-config.xml"/>
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="UserInfoDAO" class="com.bitfone.smartdm.dao.impl.UserInfoDAO">
<property name="sqlMapClient" ref="sqlMapClient"/>
</bean>
蔡超
HP 軟件架構(gòu)師
軟件架構(gòu)顧問
SCEA
IBM Certified Solution Designer for OOA&D vUML2
Chaocai2001@yahoo.com.cn