每次有新的 Http 请求时,我都需要更改当前使用的数据库,并且其名称是 Http URL 请求的一部分。 我正在尝试使用以下代码,但是当我调用该服务并且它正在执行时,在前一个服务完成之前我无法再次调用,否则它会崩溃。 我注意到问题是“未选择数据库”,但我不知道如何更改数据库而不崩溃:( 如果还没有,则必须通过代码自动创建数据库和表,因此我使用 Flyway。
我需要使用通过请求的 url 从用户传递的名称 网址模式是: .../api/v1/{db_name}/... 我正在使用 jdbcTemplate,但欢迎使用 JPA 解决方案:)
try { DriverManagerDataSource dataSource = (DriverManagerDataSource) jdbcTemplate.getDataSource(); String urlBase = env.getProperty("spring.datasource.url"); dataSource.setUrl(urlBase); dataSource.setSchema(name); Flyway flyway = Flyway.configure() .dataSource(dataSource) .defaultSchema(name) .load(); flyway.migrate(); dataSource.setUrl(urlBase+name); return true; }catch (Exception e){ e.printStackTrace(); }`
当我从两个不同的客户端调用链接两次时出现异常:
StatementCallback; uncategorized SQLException for SQL [INSERT INTO statistiche_plu_giornaliere (id, id_dbLocale, idDevice, id_plu, descrizione, importo_totale, qta_totale_plu, qta_reso_storno, qta_reale, data, importo_sconti, importo_maggiorazioni, importo_reale, resi, id_reparto, tipo_riga) VALUES (0,256,'0AB1115556633569',0,'1LT PROSECCO',24.000000,2.000000,0.000000,2.000000,'',0.000000,0.000000,24.000000,0.000000,0,0)]; SQL state [3D000]; error code [1046]; No database selected; nested exception is java.sql.SQLException: No database selected at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1542) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:393) at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:558) at com.trei.statistiche_cloud.db.DbHandler.updateStatisticheGiornaliere(DbHandler.java:119) at com.trei.statistiche_cloud.http.RestController.aggiornaDb(RestController.java:49) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) at javax.servlet.http.HttpServlet.service(HttpServlet.java:696) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) at javax.servlet.http.HttpServlet.service(HttpServlet.java:779) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354) at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:142) at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:82) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:833) Caused by: java.sql.SQLException: No database selected at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) at com.mysql.cj.jdbc.StatementImpl.executeUpdateInternal(StatementImpl.java:1334) at com.mysql.cj.jdbc.StatementImpl.executeLargeUpdate(StatementImpl.java:2084) at com.mysql.cj.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1245) at org.springframework.jdbc.core.JdbcTemplateUpdateStatementCallback.doInStatement(JdbcTemplate.java:546) at org.springframework.jdbc.core.JdbcTemplateUpdateStatementCallback.doInStatement(JdbcTemplate.java:543) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:381)`
我认为你的用例非常危险,因为你基本上是通过 HTTP/s 调用提供数据库的秘密,其他不便之处包括:
为每个请求加载数据库将显着增加应用程序的响应时间
导致可扩展性和资源消耗问题。
相反,通常建议将 Spring Boot 应用程序设置为在启动后立即启动数据库连接,并在程序的剩余生命周期中保持其打开状态。此策略可实现更高的可扩展性和更快的数据库访问速度。
如果需要为同一个应用程序配置多个数据库,您可以手动定义多个数据源。根据每个请求,您可以选择要查询的数据库