使用 Spring Boot 和 Spring JDBC 在 oracle 中设置默认模式 = SOMETHING

Posted

技术标签:

【中文标题】使用 Spring Boot 和 Spring JDBC 在 oracle 中设置默认模式 = SOMETHING【英文标题】:Set default schema = SOMETHING in oracle using Spring Boot and Spring JDBC 【发布时间】:2016-06-22 16:17:53 【问题描述】:

我现在正在使用 oracle 和 spring jdbc,但我不想在我的 sql 语句中使用架构:

示例:从 SCHEMA.table 中选择 *

有没有办法在 application.properties 或 application.yml 中设置默认架构?

【问题讨论】:

也许你可以分享你当前的配置。 【参考方案1】:

假设您使用spring数据源定义数据库连接,您可以在定义数据源配置时设置默认架构:

spring.datasource.schema = #value for your default schema to use in database

您可以在这里找到更多信息:Spring Boot Reference Guide. Appendix A. Common application properties


经过一些研究,看起来 Oracle 驱动程序不允许您设置要使用的默认架构,如下所述:

Default Schema in Oracle Connection URL

从该帖子中,您有两个选择:

    在执行您的语句之前执行此语句:

    ALTER SESSION SET CURRENT_SCHEMA=yourSchema
    

    为您的表/视图/等创建同义词(如果我们谈论的是数据库中的大量元素,我觉得这很麻烦)。

我建议使用第一个选项。据我所知,Spring boot 在检索连接时没有提供执行语句的简单方法,因此最好的办法是使用 getConnection 方法(或从数据中检索连接的方法)周围的方面source) 并在那里执行语句。


根据您的评论,更简单的解决方法是使用spring.datasource.schema 中的脚本:

spring.datasource.schema = schema.sql

然后是一个包含以下内容的文件 squema.sql:

ALTER SESSION SET CURRENT_SCHEMA=mySchema

【讨论】:

它不起作用。 spring.datasource.url=jdbc:oracle:thin:@server:1521:orcl spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver spring.datasource.username=joe spring.datasource.password=pepito spring .datasource.schema=SCHEMA_PA 我使用以下属性配置我的项目:spring.datasource.url=jdbc:oracle:thin:@server:1521:orcl spring.datasource.driver-class-name=oracle.jdbc.driver。 OracleDriver spring.datasource.username=luchito spring.datasource.password=funca spring.datasource.schema=schema.sql 和我的schema.sql 有alter session set current_schema=CELTIC_PA 如果您使用连接池,这将不起作用,因为脚本仅使用一个连接执行,而您想在所有连接上执行它。 @LuiggiMendoza 我通过使用特定于我正在使用的连接池的属性解决了这个问题:spring.datasource.hikari.connection-init-sql=ALTER SESSION... 我见过类似的其他连接池也存在属性【参考方案2】:

在 spring boot 中,我找到了另一种方法,

@Bean
@ConfigurationProperties(prefix="spring.datasource")
public DataSource dataSource(@Value("$spring.datasource.schema") String schema) 
    DataSource datasource = DataSourceBuilder.create().build();
    if(!schema.isEmpty() && datasource instanceof org.apache.tomcat.jdbc.pool.DataSource)
            ((org.apache.tomcat.jdbc.pool.DataSource) datasource).setInitSQL("ALTER SESSION SET CURRENT_SCHEMA=" + schema);
    
    return datasource;
 

【讨论】:

这对我不起作用。抱怨缺少包:org.apache.tomcat.jdbc 现在有一个配置属性可以设置这个值:spring.datasource.tomcat.init-s-q-l 有同样的问题。首先,Hibernate 抱怨数据库连接已关闭(Connection.close()),通过使用 testOnBorrow=true 更正它,但是现在,一旦第一个连接断开,第二个连接就没有定义数据库模式,即使我使用 hibernate.default_schema 选项。这是一个错误还是什么?【参考方案3】:

如果您使用 hikari,请使用 spring.datasource.hikari.schema=YOUR_SCHEMA。 使用 Oracle 与 SpringBoot + tomcat 一起为我工作。

【讨论】:

【参考方案4】:

我找到了另一种方法来解决这个问题,通过更新实体类

@Table(schema = "SCHEMA_NAME" ,name = "TABLE_NAME")

【讨论】:

在 tomcat 中不工作,tomcat 会响应错误“Schema 'SCHEMA_NAME' not found 您是否使用实际的架构名称而不是“SCHEMA_NAME”? 不..我不是那个愚蠢的人..如果我们使用tomcat它就不起作用 能否请您从您看到的错误中发布完整的堆栈跟踪。【参考方案5】:

我遇到了currently accepted answer 的问题;具体来说,模式只会从初始连接更改。如果您的应用使用连接池,则需要配置池以对每个连接应用 SQL。

例如,在 Spring Boot 1.5.x (Tomcat) 中使用默认的 jdbc 池:

spring.datasource.tomcat.init-s-q-l = ALTER SESSION SET CURRENT_SCHEMA=mySchema

【讨论】:

为我工作!谢谢!对于使用 Oracle 的人来说,这是最简单的解决方案... @Michael R:如果Spring Boot应用程序部署在jboss上,是否会使用该属性,因为该属性适用于tomcat? 这个答案现在已经很老了,只适用于使用 Tomcat JDBC 连接池的 Spring Boot 1.x 应用程序。如果您要部署到单独的应用服务器,则取决于您计划如何配置 JDBC 连接池。如果你在你的应用服务器中配置它(很常见),你会以不同的方式配置它。我怀疑如今将 Spring Boot 应用程序部署为 WAR 而不是使用嵌入式服务器是一种非常不常见的配置。【参考方案6】:

以您的用户身份连接到数据库,您可以创建一个触发器,每次登录时都会更改架构:

CREATE OR REPLACE TRIGGER LOGON_TRG 
  AFTER LOGON ON SCHEMA
BEGIN
     EXECUTE IMMEDIATE 'ALTER SESSION SET CURRENT_SCHEMA = foo';
EXCEPTION 
  when others 
    then null;
END;
/  

【讨论】:

【参考方案7】:

另一种选择是创建数据源包装器。正常创建数据源,然后创建转发除 getConnection 方法之外的所有方法的包装器。对于那些我刚刚添加 SQL 来设置架构的人。我们有多个数据源,这允许我们为每个数据源指定不同的模式。如果有人知道这是否有问题,我会喜欢 cmets。或者,如果有使用这些属性的替代方法。

【讨论】:

以上是关于使用 Spring Boot 和 Spring JDBC 在 oracle 中设置默认模式 = SOMETHING的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot日志配置

如何告诉 Spring Boot 忽略 Jetty 并始终使用 Tomcat?

Spring Boot中如何保护DataSource的用户名和密码?

多个数据库使用相同的域模型和 Spring Boot 和 Spring Data JPA

Spring Boot实践——基础和常用配置

spring boot j集成seagger 加入拦截器后 swagger 不能访问