Java Springboot JDBCTemplate多数据库

Java Springboot JDBCTemplate多数据库,java,Java,我在Springboot应用程序中配置了两个数据库(同一个模式一个是QA,另一个是PROD DB),这里的想法是我不想部署两个应用程序实例来与每个DB对话,而是在登录屏幕上,用户将选择要使用的数据库,然后应用程序将连接到数据库并提取所需数据。问题是如何在DAO层中使用@Qualifier(“firstDB”)或@Qualifier(“secondDB”)动态选择数据库。请注意,我在会话对象中有用户选择的数据库值,因此显然我不能或不应该访问DAO层中的会话数据,因为我想单独保留DAO。请帮助我动态

我在Springboot应用程序中配置了两个数据库(同一个模式一个是QA,另一个是PROD DB),这里的想法是我不想部署两个应用程序实例来与每个DB对话,而是在登录屏幕上,用户将选择要使用的数据库,然后应用程序将连接到数据库并提取所需数据。问题是如何在DAO层中使用@Qualifier(“firstDB”)或@Qualifier(“secondDB”)动态选择数据库。请注意,我在会话对象中有用户选择的数据库值,因此显然我不能或不应该访问DAO层中的会话数据,因为我想单独保留DAO。请帮助我动态选择数据库连接

数据库配置:

@Bean(name = "jdbcTemplate")
@Autowired
public JdbcTemplate jdbcTemplate(@Qualifier("dataSourceOne") DataSource dsCustom) {
    return new JdbcTemplate(dsCustom);
}
DAO:

@Autowired
private JdbcTemplate jdbcTemplate;

public TidalAlertsDAOImpl(JdbcTemplate template) {
    this.jdbcTemplate = template;
}
解决方案:

@Configuration
public class DataSourceConfig {
    @Bean(name = "dataSourceOne")
    @Primary
    public DataSource dataSource() {
        return DataSourceBuilder
                .create()
                .username("USERNAME")
                .password("Password")
                .url("jdbc:oracle:thin:@localhost.com:1521:DV")
                .driverClassName("oracle.jdbc.driver.OracleDriver")
                .build();
    }

    @Bean(name = "dataSourceTwo")
    public DataSource dataSourceTwo() {
        return DataSourceBuilder
                .create()
                .username("USERNAME")
                .password("Password")
                .url("jdbc:oracle:thin:@localhost.com:1521:QA")
                .driverClassName("oracle.jdbc.driver.OracleDriver")
                .build();
    }

    @Bean(name = "jdbcTemplate")
    @Autowired
    public JdbcTemplate jdbcTemplate(@Qualifier("dataSourceOne") DataSource dsCustom) {
        return new JdbcTemplate(dsCustom);
    }

    public JdbcTemplate getJDBCTemplate(){
        String environmnet = null;
        JdbcTemplate jdbcTemplate = null;
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpSession session = requestAttributes.getRequest().getSession();
        if(session.getAttribute("databaseName") != null){
             environmnet = (String) session.getAttribute("databaseName");
             if(environmnet.equals("Development - QA")){
                 System.out.println("Sected Database is:" + environmnet);
                 jdbcTemplate = new JdbcTemplate(dataSourceTwo());
             }else if(environmnet.equals("Sandbox - DV")){
                 System.out.println("Sected Database is:" + environmnet);
                 jdbcTemplate = new JdbcTemplate(dataSource());
             }
        }
        return jdbcTemplate;
    }

这是一个棘手的问题。是否有多个用户登录到应用程序?在这种情况下,您必须将用户映射到所选连接。使用注释在DAO中注入连接是困难的,因为数据库连接处于应用程序级别。您必须检索用于该用户的连接,然后使用相应的连接。

这是一个棘手的问题。是否有多个用户登录到应用程序?在这种情况下,您必须将用户映射到所选连接。使用注释在DAO中注入连接是困难的,因为数据库连接处于应用程序级别。您必须检索用于该用户的连接,然后使用相应的连接。

多个用户将访问该应用程序,但他们不会键入用户名或类似的内容。他们只是从下拉列表中选择数据库。这是一个内部应用程序,大多数DB不读取更新或提交。所以我猜这是基于每个请求的。类型连接可以在提交请求时作为参数提交,该参数可用于决定使用哪个连接(这是一个潜在的安全隐患。同样,与非prod和prod环境进行相同的应用程序对话本身不是一个好的设计。我建议创建两个应用程序实例-一个用于QA,另一个用于prod(如果可能的话))。我想说的是,即使它是一个内部应用程序,并且只有读访问权限,将来也可能有人授予写访问权限来执行某些操作。这只是为了避免这种情况。但说到实际问题,解决方案可能是将请求中的连接类型作为参数传递,然后将其映射到相应的连接。我想我找到了方法,下面是它的工作原理。请告诉我是否有更好的方法。请查看原始帖子中的最新代码。特别是方法getJDBCTemplate()。这看起来没问题。尽管您可能希望使用数据源1和数据源2创建两个JDBC模板的单个实例,而不是每次getJdbcTemplate()初始化一个新的JDBC模板方法被调用。多个用户将访问该应用程序,但他们不会键入用户名或类似的内容。他们只是从下拉列表中选择数据库。这是内部应用程序,大多数数据库不会读取更新或提交。因此我猜这是基于每个请求的。提交时,类型连接可以作为参数提交重新定义请求并使用param来决定使用哪个连接(这是一个潜在的安全隐患。同样,让同一个应用程序与非prod和prod环境对话本身不是一个好的设计。我建议创建两个应用程序实例-一个用于QA,另一个用于prod(如果可能的话))。我想说的是,即使它是一个内部应用程序,并且只有读访问权限,将来也可能有人授予写访问权限来执行某些操作。这只是为了避免这种情况。但说到实际问题,解决方案可能是将请求中的连接类型作为参数传递,然后将其映射到相应的连接。我想我找到了方法,下面是它的工作原理。请告诉我是否有更好的方法。请查看原始帖子中的最新代码。特别是方法getJDBCTemplate()虽然您可能希望使用数据源1和2创建两个JDBC模板的单个实例,而不是每次调用getJdbcTemplate()方法时都初始化一个新的JDBC模板。