亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

動態更改Spring數據源

動態更改Spring數據源

犯罪嫌疑人X 2019-12-26 09:53:57
我有一個Spring應用程序,我想動態更改數據源。當輸入DS URL時,Spring Bean和所有依賴項將自動更新。我知道這有些奇怪,但是無論如何我都想實現。我的Spring配置如下:<bean id="majorDataSource" class="org.postgresql.ds.PGSimpleDataSource">    <property name="serverName" value="${jdbc.serverName}" />    <property name="portNumber" value="${jdbc.portNumber}" />    <property name="user" value="${jdbc.username}" />    <property name="password" value="${jdbc.password}" />    <property name="databaseName" value="${jdbc.databaseName}" /></bean><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    <property name="dataSource" ref="majorDataSource"/></bean><tx:annotation-driven transaction-manager="transactionManager"/><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">    <property name="dataSource" ref="majorDataSource"/>    <property name="configLocation" value="classpath:sqlmap-config.xml"/></bean>問題是:JDBC URL存儲在屬性中,可以在運行時更改。更改URL后,我需要重新創建數據源,可能還需要重新創建相關對象。我不知道如何在春季優雅地做它?我知道Spring確實可以基于一個鍵動態路由數據源,但是數據源URL是在Spring中預定義的,不會更改運行時。這不是我的情況。
查看完整描述

3 回答

?
炎炎設計

TA貢獻1808條經驗 獲得超4個贊

您可以通過擴展spring 并覆蓋應該返回引用要使用的數據源spring bean的鍵的方法來使用spring的AbstractRoutingDataSourcedetermineCurrentLookupKey()。


在spring source的博客上看一下這篇博客文章,它將向您展示如何使用該功能的示例。


基本上要回答您的問題,您需要做的是在XML配置中將兩個數據源定義為不同的spring bean。無需動態創建一個,spring會同時加載兩者,并根據determineCurrentLookupKey()方法中的條件動態使用一個或另一個。


這將導致類似:


XML配置


<!-- first data source -->

<bean id="majorDataSource" class="org.postgresql.ds.PGSimpleDataSource">

    <property name="serverName" value="${jdbc.major.serverName}" />

    <property name="portNumber" value="${jdbc.major.portNumber}" />

    <property name="user" value="${jdbc.major.username}" />

    <property name="password" value="${jdbc.major.password}" />

    <property name="databaseName" value="${jdbc.major.databaseName}" />

</bean>

<!-- second data source -->

<bean id="minorDataSource" class="org.postgresql.ds.PGSimpleDataSource">

    <property name="serverName" value="${jdbc.minor.serverName}" />

    <property name="portNumber" value="${jdbc.minor.portNumber}" />

    <property name="user" value="${jdbc.minor.username}" />

    <property name="password" value="${jdbc.minor.password}" />

    <property name="databaseName" value="${jdbc.minor.databaseName}" />

</bean>

<!-- facade data source -->

<bean id="dataSource" class="blog.datasource.CustomerRoutingDataSource">

   <property name="targetDataSources">

      <map>

         <entry key="MINOR" value-ref="minorDataSource"/>

         <entry key="MAJOR" value-ref="majorDataSource"/>

      </map>

   </property>

   <property name="defaultTargetDataSource" ref="majorDataSource"/>

</bean>

<!-- wiring up -->

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

    <property name="dataSource" ref="dataSource"/>

</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

    <property name="dataSource" ref="dataSource"/>

    <property name="configLocation" value="classpath:sqlmap-config.xml"/>

</bean>

爪哇


public class MyRoutingDataSource extends AbstractRoutingDataSource {

   @Override

   protected Object determineCurrentLookupKey() {

      // get the current url

      HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();

      if (request.getRequestURL().toString().endsWith("/minor"))

          return "MINOR";

      else

          return "MAJOR";

   }

}


查看完整回答
反對 回復 2019-12-26
?
德瑪西亞99

TA貢獻1770條經驗 獲得超3個贊

我不確定這是否是正確的方法,但是您可以做的是這樣的事情。


<bean id="majorDataSource" class="org.postgresql.ds.PGSimpleDataSource">

    <property name="serverName" value="dummydata" />

    <property name="portNumber" value="dummydata" />

    <property name="user" value="dummydata" />

    <property name="password" value="dummydata" />

    <property name="databaseName" value="dummydata" />

</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

    <property name="dataSource" ref="majorDataSource"/>

</bean>


<tx:annotation-driven transaction-manager="transactionManager"/>

并且在Java類中


public class TestTransaction {


   @Autowired

   private DataSourceTransactionManager manager;


   private PlatformTransactionManager transactionManager;


   public testExecution(DataSource ds) {

       manager.setDataSource(ds);

       transactionManager = manager;

       TransactionDefinition def = new DefaultTransactionDefinition();

       TransactionStatus status = transactionManager.getTransaction(def);

       try {

           jdbcTemplate.update();

           transactionManager.commit(status);

       } catch (Exception ex) {

           transactionManager.rollback(status);

       }

   }

}

請建議這種方法是否可以工作,因為我還是Spring的新手


查看完整回答
反對 回復 2019-12-26
?
慕尼黑的夜晚無繁華

TA貢獻1864條經驗 獲得超6個贊

我使用主要數據庫和次要數據庫進行故障轉移。當主要數據庫失敗時,我將提升次要數據庫為主要數據庫。然后,我需要設置第三個數據庫作為備用數據庫,其URL將是動態的,無法在此處預定義。無論如何,也許我可以強制對主要數據庫和次要數據庫使用靜態IP,因此無需動態更改URL。

查看完整回答
反對 回復 2019-12-26
  • 3 回答
  • 0 關注
  • 540 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號