久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Spring多數(shù)據(jù)源的配置和使用

 windli筆記 2012-09-25

Spring多數(shù)據(jù)源的配置和使用

   最近開發(fā)一個數(shù)據(jù)同步的小功能,需要從A主機的Oracle數(shù)據(jù)庫中把數(shù)據(jù)同步到B主機的Oracle庫中,。當然能夠用dmp腳本或者SQL腳本是最 好,,但是對于兩邊異構(gòu)的表結(jié)構(gòu)來說,,直接導(dǎo)入不可行,。然后在需要實時同步的情況下用存儲過程也不可行了。寫一個數(shù)據(jù)同步的小程序是個不錯的選擇,。使用框架 的封裝和連接池是必須的,Spring是首選,,這里我們同樣需要Spring的多數(shù)據(jù)源連接配置方式,。 其實再進行項目開發(fā)的時候,,一個項目有可能不止用到一個數(shù)據(jù)源,為了提高數(shù)據(jù)庫的水平伸縮性,,需要對多個數(shù)據(jù)庫實例進行管理,,需要配置多數(shù)據(jù)源。

 

     1. 配置多個數(shù)據(jù)源

     這里以兩個c3p0數(shù)據(jù)庫連接池的數(shù)據(jù)源作為實例,。在Spring框架下使用c3p0的數(shù)據(jù)庫需要加入c3p0-0.9.1.2.jar(現(xiàn)在最新的)這個支持包,。這里以數(shù)據(jù)同步項目為例:

   數(shù)據(jù)來源庫的連接池數(shù)據(jù)源配置:

Xml代碼   收藏代碼
  1. <bean id="dataSourceFrom" class="com.mchange.v2.c3p0.ComboPooledDataSource">  
  2.     <property name="driverClass" value="${jdbc.driver}" />  
  3.     <property name="jdbcUrl" value="${jdbc.from.url}" />  
  4.     <property name="user" value="${jdbc.from.username}" />  
  5.     <property name="password" value="${jdbc.from.password}" />  
  6.     <property name="autoCommitOnClose" value="true" />  
  7.     <property name="checkoutTimeout" value="${cpool.checkoutTimeout}" />  
  8.     <property name="initialPoolSize" value="${cpool.minPoolSize}" />  
  9.     <property name="minPoolSize" value="${cpool.minPoolSize}" />  
  10.     <property name="maxPoolSize" value="${cpool.maxPoolSize}" />  
  11.     <property name="maxIdleTime" value="${cpool.maxIdleTime}" />  
  12.     <property name="acquireIncrement" value="${cpool.acquireIncrement}" />  
  13.     <property name="maxIdleTimeExcessConnections" value="${cpool.maxIdleTimeExcessConnections}" />  
  14. </bean>  

 數(shù)據(jù)插入庫的連接池數(shù)據(jù)源配置:

Xml代碼   收藏代碼
  1. <bean id="dataSourceTo" class="com.mchange.v2.c3p0.ComboPooledDataSource">  
  2.     <property name="driverClass" value="${jdbc.driver}" />  
  3.     <property name="jdbcUrl" value="${jdbc.to.url}" />  
  4.     <property name="user" value="${jdbc.to.username}" />  
  5.     <property name="password" value="${jdbc.to.password}" />  
  6.     <property name="autoCommitOnClose" value="true" />  
  7.     <property name="checkoutTimeout" value="${cpool.checkoutTimeout}" />  
  8.     <property name="initialPoolSize" value="${cpool.minPoolSize}" />  
  9.     <property name="minPoolSize" value="${cpool.minPoolSize}" />  
  10.     <property name="maxPoolSize" value="${cpool.maxPoolSize}" />  
  11.     <property name="maxIdleTime" value="${cpool.maxIdleTime}" />  
  12.     <property name="acquireIncrement" value="${cpool.acquireIncrement}" />  
  13.     <property name="maxIdleTimeExcessConnections" value="${cpool.maxIdleTimeExcessConnections}" />  
  14. </bean>  

   注意:上面url,user,,password等值是從classpath下的jdbc.properties中取得的,。

   通過Spring獲取屬性文件中的值,以供配置文件使用:

Xml代碼   收藏代碼
  1. <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  2.     <property name="locations" value="classpath:jdbc.properties" />  
  3. </bean>  

 

     2. 擴展Spring的AbstractRoutingDataSource抽象類,,實現(xiàn)動態(tài)數(shù)據(jù)源,。

    AbstractRoutingDataSource中的抽象方法determineCurrentLookupKey是實現(xiàn)數(shù)據(jù)源的route的核心.這里對該方法進行Override。

Java代碼   收藏代碼
  1. public class DynamicDataSource extends AbstractRoutingDataSource{  
  2.   
  3.     @Override  
  4.     protected Object determineCurrentLookupKey() {  
  5.         return DBContextHolder.getDBType();  
  6.     }  
  7. }  

   上下文DbContextHolder為一線程安全的ThreadLocal,,具體代碼如下:

Java代碼   收藏代碼
  1. public class DBContextHolder{  
  2.     public static final String DATA_SOURCE_FROM = "dataSourceFrom";  
  3.     public static final String DATA_SOURCE_TO = "dataSourceTo";  
  4.       
  5.     private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();  
  6.       
  7.     public static void setDBType(String dbType) {  
  8.         contextHolder.set(dbType);  
  9.     }  
  10.       
  11.     public static String getDBType() {  
  12.         return contextHolder.get();  
  13.     }  
  14.       
  15.     public static void clearDBType() {  
  16.         contextHolder.remove();  
  17.     }  
  18. }  

 

    3.配置動態(tài)數(shù)據(jù)源

 將DynamicDataSource Bean加入到Spring的上下文xml配置文件中去,同時配置DynamicDataSource的targetDataSources(多數(shù)據(jù)源目標)屬性的Map映射,。

Xml代碼   收藏代碼
  1. <bean id="dynamicDataSource" class="datasource.DynamicDataSource" >  
  2.     <!-- 通過key-value的形式來關(guān)聯(lián)數(shù)據(jù)源 -->  
  3.     <property name="targetDataSources">  
  4.         <map>  
  5.             <entry value-ref="dataSourceFrom" key="dataSourceFrom"></entry>  
  6.             <entry value-ref="dataSourceTo" key="dataSourceTo"></entry>  
  7.         </map>  
  8.     </property>  
  9.     <property name="defaultTargetDataSource" ref="dataSourceFrom" />  
  10. </bean>   

 

    4.使用動態(tài)數(shù)據(jù)源

    例子中DynamicDataSource是繼承與AbstractRoutingDataSource,,而 AbstractRoutingDataSource又是繼承于 org.springframework.jdbc.datasource.AbstractDataSource,AbstractDataSource 實現(xiàn)了統(tǒng)一的DataSource接口,,所以DynamicDataSource同樣可以當一個DataSource使用,。

 在Spring的JdbcTemplate使用動態(tài)數(shù)據(jù)源的配置示例:

Xml代碼   收藏代碼
  1. <!-- JdbcTemplate使用動態(tài)數(shù)據(jù)源的配置 -->  
  2. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
  3.     <property name="dataSource">  
  4.         <ref bean="dynamicDataSource" />  
  5.     </property>  
  6. </bean>  
  7.   
  8. <!-- 對JdbcTemplate的應(yīng)用封裝類 -->  
  9. <bean id="sqlBaseDAO" class="com.whty.dao.BaseDAOImpl">  
  10.     <property name="jdbcTemplate">  
  11.         <ref bean="jdbcTemplate" />  
  12.     </property>  
  13. </bean>  

在ORM框架Hibernate中的使用配置示例:

Xml代碼   收藏代碼
  1. <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">  
  2.     <!-- 和普通的dataSource用法一樣 -->  
  3.     <property name="dataSource" ref="dynamicDataSource" />  
  4.     <property name="configLocations" value="classpath:hibernate.cfg.xml" />  
  5.     <property name="hibernateProperties">  
  6.         <props>  
  7.             <prop key="hibernate.dialect">${hibernate.dialect}</prop>     
  8.     </property>  
  9. </bean>  

   

    5.事務(wù)管理

使用動態(tài)數(shù)據(jù)源的時候,可以看出和使用單數(shù)據(jù)源的時候相比,,在使用配置上幾乎沒有差別,,在進行性事務(wù)管理配置的時候也沒有差別:

使用Spring的JdbcTemplate的事務(wù)管理配置示例:

Xml代碼   收藏代碼
  1. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  2.     <property name="dataSource" ref="dynamicDataSource" />  
  3. </bean>  
  4.   
  5. <bean id="sqlBaseDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">  
  6.     <property name="transactionManager" ref="transactionManager" />  
  7.     <property name="target" ref="sqlBaseDAO" />  
  8.     <property name="transactionAttributes">  
  9.         <props>  
  10.             <prop key="insert*">PROPAGATION_REQUIRED</prop>  
  11.             <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>  
  12.         </props>  
  13.     </property>  
  14. </bean>  
 

 

使用Hibernate時的事務(wù)管理配置示例:

Xml代碼   收藏代碼
  1. <tx:annotation-driven transaction-manager="transactionManager"/>  
  2.   
  3. <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">  
  4.     <property name="sessionFactory" ref="sessionFactory" />  
  5. </bean>  

 

 

    6.動態(tài)數(shù)據(jù)源的管理控制

如何選擇控制每個業(yè)務(wù)中需要的具體數(shù)據(jù)源,可是使用手動控制:

Java代碼   收藏代碼
  1. ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
  2. BaseDAO dao = (BaseDAO) context.getBean("sqlBaseDAO", BaseDAOImpl.class);  
  3.   
  4. try {  
  5.     DBContextHolder.setCustomerType(DBContextHolder.DATA_SOURCE_FROM);  
  6.     System.err.println(dao.select("select count(*) sum from TEST t ").get(0).get("SUM"));  
  7.     DBContextHolder.setCustomerType(DBContextHolder.DATA_SOURCE_TO);  
  8.     System.err.println(dao.select("select count(*) sum from TEST t ").get(0).get("SUM"));  
  9.       
  10. catch (Exception e) {  
  11.     e.printStackTrace();  
  12. }  

也可以采用AOP的控制方式:

Java代碼   收藏代碼
  1. @Aspect  
  2. public class DynamicDataSourceAspect {  
  3.     @Pointcut("execution (public service.impl..*.*(..))")  
  4.     public void serviceExecution(){}  
  5.       
  6.     @Before("serviceExecution()")  
  7.     public void setDynamicDataSource(JoinPoint jp) {  
  8.         for(Object o : jp.getArgs()) {  
  9.             //處理具體的邏輯 ,,根據(jù)具體的境況CustomerContextHolder.setCustomerType()選取DataSource  
  10.         }  
  11.     }  
  12. }  

 

  7.總結(jié)

   通過擴展Spring的AbstractRoutingDataSource可以很好的實現(xiàn)多數(shù)據(jù)源的rout效果,,而且對擴展更多的數(shù)據(jù)源有良好的伸縮 性,只要增加數(shù)據(jù)源和修改DynamicDataSource的targetDataSources屬性配置就好,。在數(shù)據(jù)源選擇控制上,,可以采用手動控制 (業(yè)務(wù)邏輯并不多的時候),也可以很好的用AOP的@Aspect在Service的入口加入一個切面@Pointcut,在@Before里判斷 JoinPoint的類容選定特定的數(shù)據(jù)源,。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多