【问题标题】:How to specify table schema in spring-data-jdbc如何在 spring-data-jdbc 中指定表模式
【发布时间】:2021-02-14 03:51:09
【问题描述】:

在我的项目中,我使用 spring-data-jdbc 版本 2.0.4.RELEASE,但我遇到了如何为表指定模式的问题。实体类是这样的

@Data
@Table(value = "alpha.op_organization")
public class OrganizationEntity {
   @Id
   private Long id;
   @Column(name="name")
   private String name;
}

如果我尝试使用 jdbc 存储库方法 save 像这样保存实体

OrganizationEntity organization = new OrganizationEntity();
organization.setName("OrgName1");
organizationRepository.save(organisation)

我有异常“关系alpha.op_organization不存在。对应的sql查询是

INSERT INTO "alpha.op_organization" ("name") VALUES (?)

我。 e.事实证明,我们试图在“alpha.op_organization”表中插入一个条目,而不是在 alpha 模式的表 op_organization 中。

我想自定义 NamingStrategy 以返回架构 alpha 但没有运气。

@Configuration
public class AppConfig extends AbstractJdbcConfiguration {
   @Bean
   public NamingStrategy namingStrategy() {
      return new NamingStrategy() {

         @Override
         public String getSchema() {
            return "alpha";
         }
      };
   }
}

有没有办法在spring-data-jdbc中指定表模式?

【问题讨论】:

    标签: spring-data-jdbc


    【解决方案1】:

    抱歉来晚了,但我想我可以在这里帮助其他开发人员。正如@MadMax 所提到的,指定NamingStrategy#getSchema() 并不真正适用于@Table。其实there is bug,而且在spring-data-jdbc中也有报道, 这实际上表明指定 @Table#value 不能与 NamingStrategy 一起使用。

    好消息是在 spring-data-jdbc 中打开了一个Pull Request 来解决这个问题。此 Pull Request 引入的更改会将 schema 参数添加到 @Table 注释,如果您愿意,这将允许您显式指定每个表的架构。此 PR 也将消除此错误。

    你现在能做什么:好吧,如果你很不幸,你需要结合使用@Table#valueNamingStrategy#getSchema() - 它不会起作用。如果你真的需要指定模式,你现在需要去掉@Table注解。如果您这样做,来自 NamingStrategy 的架构将正确应用。

    【讨论】:

      【解决方案2】:

      如果你正在使用

      import org.springframework.data.relational.core.mapping.Table;
      

      Spring 尝试构建查询

      INSERT INTO "alpha.op_organization" ("name") VALUES (?)

      但我们需要

      INSERT INTO "alpha"."op_organization" ("name") VALUES (?)

      尝试:

      @Table(value = "alpha\".\"op_organization")
      

      【讨论】:

        【解决方案3】:

        在JDBC连接url中赋值currentSchema参数。

        例如:jdbc:postgresql://server/catalog?currentSchema=schema

        这让我在不同的表名方面更加灵活,但无需在 @Table 注释中再次描述相同的模式名称。

        Postgres JDBC connections documentation

        【讨论】:

        • 如果表在不同的模式中,这个解决方案似乎不起作用
        • @MadMax 您必须为具有不同架构的特定 Entity 添加 @Table("another_schema.table_name") 注释。对于那些具有不同表名但架构相同的Entity,则无需在@Table 注释中再次显式指定架构,而只需使用表名,例如@Table("different_table_name")
        • 实际上我已经尝试过这种可能性,但没有运气。它接缝 jdbc 或其他人将其视为表名“another_schema.table_name”(如单个未分割的表名)。我是这么认为的,因为我从 undelying db 驱动程序“关系“another_schema.table_name”不存在”中得到了异常。当然,这种关系确实存在。
        • @MadMax 这似乎很奇怪,在我看来它正在工作,我将 Postgres 和 Spring Data JDBC 2.1.5 与 Spring Boot 2.4.3 一起使用。
        • 谢谢,我会尝试使用这个版本的 jdbc。也许它会起作用。
        【解决方案4】:

        我使用 postgresql + HikariDataSource。 所以就我而言:

         @Bean
         public DataSource dataSource() {
        
                HikariConfig hikariConfig = new HikariConfig();
        ...
                if(schema != null && !schema.isEmpty()){
                    hikariConfig.setConnectionInitSql("SET SEARCH_PATH TO " + schema);
                }
                
                HikariDataSource dataSource = new HikariDataSource(hikariConfig);
                return dataSource;
          }
        

        实体注释如下: @Table("用户") 正确映射到 service.user

        【讨论】:

          【解决方案5】:

          目前这样做的方法是定义一个NamingStrategy。示例取自this integration 测试:

          @Bean
          NamingStrategy namingStrategy() {
              return new NamingStrategy() {
                  @Override
                  public String getSchema() {
                      return "other";
                  }
              };
          }
          

          【讨论】:

          • 此解决方案仅适用于实体类未使用“@Table”注释进行注释的情况。如果是类,我的自定义 NamingStrategy 不会调用。您能解释一下如何使用命名策略和“@Table”注释设置架构吗?
          猜你喜欢
          • 2017-08-14
          • 2018-03-07
          • 2019-06-05
          • 1970-01-01
          • 2017-08-08
          • 1970-01-01
          • 2017-07-17
          • 2017-09-08
          • 2021-02-02
          相关资源
          最近更新 更多