当前位置: 首页 > 知识库问答 >
问题:

动态更改Spring数据源

石思淼
2023-03-14

我有一个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>

问题是:

>

一旦URL被更改,我需要重新创建数据源,可能还有依赖对象。我不知道如何在Spring优雅地做这件事?

我知道Spring可以基于一个键动态路由数据源,但数据源URL是在Spring中预定义的,不会更改运行时。这不是我的情况。

共有2个答案

宗晟
2023-03-14

我不确定这是不是正确的方法,但你能做的就是这样。

<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

毛越
2023-03-14

您可以通过扩展Spring的AbstractRoutingDataSource并覆盖应该返回引用要使用的数据源的Spring bean的键的方法确定货币查找键()来使用Spring的AbstractRoutingDataSource。

看看Spring source博客上的这篇博客文章,它将向您展示如何使用该功能的示例

基本上,为了回答您的问题,您需要做的是在您的XML配置中将两个数据源定义为不同的Spring bean。没有必要动态创建一个,Spring将加载两个,并根据您在确定中的条件动态使用一个或另一个。

这将导致如下结果:

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>

Java语言

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";
   }
}

 类似资料:
  • 问题内容: 我有一个Spring应用程序,我想动态更改数据源。当输入DS URL时,Spring Bean和所有依赖项将自动更新。我知道这有些奇怪,但是无论如何我都想实现。我的Spring配置如下: 问题是: JDBC URL存储在属性中,可以在运行时更改它。 更改URL后,我需要重新创建数据源,可能还需要重新创建相关对象。我不知道Spring如何优雅地做呢? 我知道Spring确实可以基于一个键

  • 我正在尝试对我的应用程序做类似的事情。我正在使用以下版本的Spring boot和Cassandra: Spring数据卡桑德拉-2.0。8.释放Spring护套启动器父级-2.0。4.RELEASE我需要动态更改Cassandra的一些属性(主要是主机名),并希望它与应用程序建立新的连接。对于配置更改,我们有内部云配置更改管理,它在更改时运行良好,并侦听更改。这是我的班级: 但是,当我尝试将@R

  • 我想在Spring MyBatis项目中动态更改数据源属性。 问题是在Spring MyBatis集成中,我们无法在运行时动态设置数据源属性。 目前我正在使用以下代码来设置凭据: 我尝试使用UserCredentialsDataSourceAdapter选项在运行时更改密码,但我无法将用于连接的数据源对象作为MyBatis返回 我被困在这里了,我不能使用数据源元素ds来连接MyBatis。请帮我解

  • 全部的 我是骆驼的开胃菜。我有一些问题。这里有一个场景。 文件正文中有2个字段。(seq, date, OR no.)所以,我为这个数据格式生成了pojo类。 我申请了骆驼队。几天后,关于添加名称字段,dataformat发生了更改。 所以,我们需要修改pojo类并再次重建应用程序。但我们不想再次构建应用程序并为dataformat生成pojo类。 如果我们可以在运行时使用xsd动态生成Pojo类

  • 问题内容: 我正在从数据库中成功获取数据值。我也将它们存储到一个数组中。我需要将String数组作为项的加载,以响应执行的关键操作。每当获取按键值时,如何获取按键值,就如何重新加载项目。相反,我需要动态刷新项目。 问题答案:

  • 现在,我有一个简单的Spring Boot应用程序,它为静态图像提供服务,我将这些图像放在了resources/static/img中。这对于显示实际内容来说很好,但我想解决两件事: > 我不希望这些图像中的任何一个与生成的文件捆绑在一起,我知道将这些图像放在文件夹中会做到这一点。 使用我当前的设置,为了在webapp上看到新图像,我必须将其添加到文件夹并重新启动。相反,我希望Spring提供特定