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