【问题标题】:Add prefix to table names in liquibase using Java Spring JPA [duplicate]使用Java Spring JPA为liquibase中的表名添加前缀[重复]
【发布时间】:2020-07-27 14:46:43
【问题描述】:

我正在寻找一种在 liquibase 执行我的 xml 文件时自动为我的表名添加前缀的方法。例如,如果这是我的 initial-changelog.xml:

 <changeSet id="initial_changeset" author="ME">
    <createTable tableName="EMP">
        <column name="ID" type="UUID">
            <constraints primaryKey="true" nullable="false"/>
        </column>
        <column name="REFERENCE" type="VARCHAR(250)">
            <constraints nullable="false"/>
        </column>
    </createTable>

    <createIndex tableName="EMP" indexName="IDX_EMP_REFERENCE" unique="true">
        <column name="ESS_REFERENCE"/>
    </createIndex>

    <createTable tableName="COMPANY_CAR">
        <column name="ID" type="UUID">
            <constraints primaryKey="true" nullable="false"/>
        </column>
        <column name="START_DATE" type="DATE">
            <constraints nullable="false"/>
        </column>
        <column name="END_DATE" type="DATE">
            <constraints nullable="false"/>
        </column>
    </createTable>
</changeSet>

我希望生成带有特定前缀的表,例如:

  • TBL_EMP
  • TBL_COMPANY_CAR

我可以在 XML 中指定前缀吗?还是有其他方法可以强制?

tableName 索引也应该有前缀...

我正在使用 liquibase 和一个使用 Java Spring JPA 的 MYSQL 数据库

TRY 1:我已经尝试过了,但这不会覆盖 liquibase xml 配置:

hibernate.physical_naming_strategy=be.everesst.employee.adapter.jpa.config.CustomHibernateNamingStrategy

在我的application.properties 文件中有这个

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.springframework.context.annotation.Configuration;

    @Configuration
    public class CustomHibernateNamingStrategy extends PhysicalNamingStrategy {
    
    public static final String TABLE_NAME_PREFIX = "EMPLOYEE_";
    
    @Override
    public Identifier toPhysicalTableName(final Identifier identifier, final JdbcEnvironment jdbcEnvironment) {
        return prefix(identifier);
    }

    private Identifier prefix(Identifier identifier) {
        return Identifier.toIdentifier(TABLE_NAME_PREFIX + identifier.getText());
    }
    
 }

TRY 2:我也试过了,但这也不会覆盖 liquibase xml 配置:

spring.jpa.hibernate.naming.physical-strategy=be.everesst.employee.adapter.jpa.config.PrefixPhysicalNamingStrategy 

在我的application.properties 文件中有这个

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

public class PrefixPhysicalNamingStrategy extends PhysicalNamingStrategyStandardImpl {

    public static final String TABLE_NAME_PREFIX = "EMPLOYEE_";

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        Identifier newIdentifier = new Identifier(TABLE_NAME_PREFIX + name.getText(), name.isQuoted());
        return super.toPhysicalTableName(newIdentifier, context);
    }

找到了 Liquibase 本身的解决方案:使用 modifySql 语句

(我删除了所有自定义的休眠命名策略!)

我创建了 2 个属性:

<property name="table.prefix" value="TBL_"/>
<property name="schema.name" value="PUBLIC"/>

然后添加以下语句:

    <modifySql>
        <regExpReplace replace="CREATE\ TABLE\ ${schema.name}.([\w]*)\ (.*)" with="CREATE TABLE ${schema.name}.${table.prefix}$1 $2"/>
    </modifySql>

    <modifySql>
        <regExpReplace replace="CREATE\ UNIQUE\ INDEX\ ${schema.name}.([\w]*)\ ON\ PUBLIC.([\w]*)\((.*)\)" with="CREATE UNIQUE INDEX ${schema.name}.$1 ON ${schema.name}.${table.prefix}$2($3)"/>
    </modifySql>

    <modifySql>
        <regExpReplace replace="CREATE\ INDEX\ ${schema.name}.([\w]*)\ ON\ ${schema.name}.([\w]*)\((.*)\)" with="CREATE INDEX ${schema.name}.$1 ON ${schema.name}.${table.prefix}$2($3)"/>
    </modifySql>

【问题讨论】:

  • 为什么不在更新日志中使用前缀命名它们?
  • 我们正在开发具有多个微服务和多个上下文的大型应用程序,因此我们不想在需要时手动重命名前缀......表的数量会变得非常大...... .
  • 我看到集合中只有创建表更改,因此您不需要重命名任何表。此外,您正在使用 liquibase,因此您无需手动操作。为什么需要前缀?多个微服务会连接到同一个数据库吗?如果是,那么你不应该stackoverflow.com/questions/43612866/…
  • 但这只是一个简单的例子,它不是实际的源代码...我们希望我们的表具有微服务的前缀,因为微服务可能会创建一个具有相同前缀的表名字,没有前缀就没有我们的结构......我并不是真的问我是否需要前缀,我问的是你是否知道这样做的解决方案
  • 这能回答你的问题吗? Liquibase table name prefix

标签: java spring jpa liquibase liquibase-hibernate


【解决方案1】:

创建配置文件:CustomHibernateNamingStrategy implemnts org.hibernate.boot.model.naming.PhysicalNamingStrategy

使用以下属性将其添加到休眠配置:hibernate.physical_naming_strategy

在配置文件中覆盖如下方法:

  @Override
  public Identifier toPhysicalTableName(final Identifier identifier, final JdbcEnvironment jdbcEnvironment) {
    return prefix(identifier);
  }

  private Identifier prefix(final Identifier identifier) {
    return Identifier.toIdentifier("TBL_" + identifier.getText());
  }

  @Override
  public Identifier toPhysicalCatalogName(final Identifier identifier, final JdbcEnvironment jdbcEnvironment) {
    return identifier;
  }

 
  @Override
  public Identifier toPhysicalColumnName(final Identifier identifier, final JdbcEnvironment jdbcEnvironment) {
    return identifier;
  }
 
  @Override
  public Identifier toPhysicalSchemaName(final Identifier identifier, final JdbcEnvironment jdbcEnvironment) {
    return identifier;
  }

我会建议覆盖接口的所有方法以达到一致的结果。

【讨论】:

  • 这是使用 liquibase 吗?
  • 你的第一个方法中有一些奇怪的字符......你能解决这个问题吗?
  • 是的,使用 Liquibase。并且方法名是固定的。
  • 示例 src 增强。
  • 不幸的是,这不会覆盖 liquibase 表命名
猜你喜欢
  • 2015-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-04
  • 2015-12-08
  • 2018-08-23
相关资源
最近更新 更多