如何在使用Spring JdbcTemplate时动态更改数据库/目录

8
考虑这样一种情况,所有客户端数据都存储在自己的数据库/目录中,所有这些数据库都存储在单个RDBMS(客户端数据)中。主数据(例如客户端等)保存在另一个RDBMS(主数据)中。我们如何通过JdbcTemplate动态访问客户端数据RDBMS中的特定数据库?对于我们来说,为客户端数据RDBMS中的每个数据库定义DataSource,然后动态选择一个建议here并不是一个选项,因为数据库是动态创建和销毁的。基本上我需要像JDBC的Connection.setCatalog(String catalog)一样的东西,但我没有发现Spring JdbcTemplate中有类似的东西。

也许你可以使用DelegatingDataSource包装数据源,以便在getConnection()调用时调用setCatalog() - user180100
嗯,可能一些类型的包装器可以解决问题。现在的问题是如何将相应的目录传递给这样的包装器。无论如何,这是个好点。 - pgiecek
在创建jdbcTemplate时:new JdbcTemplate(new MyDelegatingDS(dataSource, "catalogName")); 就像这样 - user180100
是的,当然,我指的是在整个解决方案的背景下,但这超出了问题本身的范围。无论如何,你不想把你的评论总结成一个答案吗?我认为它值得被接受,因为目前可能没有比“DataSource”包装器更好的解决方案了。 - pgiecek
你使用哪个数据库管理系统? - user330315
我正在使用MySQL数据库。 - pgiecek
3个回答

9
也许您可以使用 DelegatingDataSource 将数据源包装起来,在 getConnection() 中调用 setCatalog() 并在创建 JdbcTemplate 时使用包装后的数据源。
class MyDelegatingDS extends DelegatingDataSource {
  private final String catalogName;

  public MyDelegatingDS(final String catalogName, final DataSource dataSource) {
    super(dataSource);
    this.catalogName = catalogName;
  }

  @Override
  public Connection getConnection() throws SQLException {
    final Connection cnx = super.getConnection();
    cnx.setCatalog(this.catalogName);
    return cnx;
  }

  // maybe also override the other getConnection();
}

// then use like that: new JdbcTemplate(new MyDelegatingDS("catalogName", dataSource)); 

你可能想在 cnx.setCatalog() 周围添加 try/catch,并在出现异常时关闭连接。否则,你将会泄漏连接(例如,如果目录不存在)。 - Gert-Jan

6

您可以通过JdbcTemplate访问Connection

jdbcTemplate.getDataSource().getConnection().setCatalog(catalogName);

您只需要确保数据库驱动程序支持此功能。


是的,我可以使用这种方法,但我不想直接使用JDBC(ConnectionStatementResultSet,...)。这样使用JdbcTemplate是没有意义的。问题在于我想使用JdbcTemplate的接口来访问数据。 - pgiecek
@pgiecek:使用JdbcTemplate的目的是避免在使用普通JDBC时需要的样板代码。如果一个解决方案使用普通JDBC很简单和容易,那为什么不使用它呢?调用setCatalog()再简单不过了。 - user330315
是的,我同意。我喜欢JdbcTemplate,因为正如你所指出的那样,它可以避免使用JDBC样板代码。仅仅因为一个微小的连接调整,我不想直接使用JDBC。我认为@RC的解决方案是一个很好的妥协。 - pgiecek

0
jdbcTemplate.getDataSource().getConnection().setSchema(schemaName) 

这正是我需要的,用于在Postgres中切换模式。感谢@m3th0dman将我指向正确的方向。我只是添加了这一段,以防其他人像我一样搜索切换模式的答案。


我也在尝试同样的操作,但是它没有起作用。在这个语句之前和之后,我尝试打印模式,结果是相同的 - public。你还做了什么来使它工作吗? - sg1291

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接