在运行时Spring中设置@Table

时间:2018-05-23 18:38:52

标签: spring hibernate jpa

我正在编写一个spring服务来使用JPA连接到我的PostgreSQL SQL服务器。我面临的问题是如何在运行时将@Table设置为一个值。我有两个表,一个用于QA,另一个用于产品。因此,当我执行jar时,我将配置文件设置为QA或prod,但我无法获得如何将@Table设置为给定配置文件的相应表。

java -jar -Dspring.config.location=.\vmconfig -Dspring.profiles.active=qa postgre-1.0.1.jar

Properties File

server.port= 6869   
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://xxx-xxx/DB
spring.datasource.username=postgres
spring.datasource.password=xxxx
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none

@Table(name =<>) - >应根据执行jar的配置文件在运行时设置名称。

1 个答案:

答案 0 :(得分:1)

您有三种选择:

orm.xml (推荐)

您可以定义orm.xml。有了它,您可以覆盖实体的表名。 通常,您将删除资源/ META-INF文件夹中的orm.xml。但是这将适用于所有配置文件,因为Spring Boot会自动加载它。

对于您的情况,您只希望它用于指定的配置文件。为此,您需要创建LocalContainerEntityManagerFactoryBean。 (而不仅仅是设置属性)(Example here

LocalContainerEntityManagerFactoryBean上,您可以设置orm.xml的位置。

例如:

@Bean
@Profile("QA")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
        DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
    LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
    bean.setDataSource(dataSource);
    bean.setJpaVendorAdapter(jpaVendorAdapter);
    bean.setPackagesToScan("com.example.demo");
    bean.setMappingResources("orm.xml");
    return bean;
}

此配置应仅应用于所需的配置文件。

这是一个简单的orm.xml示例

<entity-mappings version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd">

<entity class="com.example.demo.EntityName">
    <table name="NEW_TABLE_NAME"></table>
</entity>

*感谢@BillFrost指出这一点。

每个环境

@EntityScan

您可以为每个环境配置提供不同的@EntityScan。因此,仅扫描QAConfiguration中的QA实体。这要求您创建具有@Table中定义的不同名称的重复实体。

我真的不喜欢这个,因为它会导致你必须维护一组QA实体和一个生产集。 这只是一个等待发生的生产问题。

重写SpringPhysicalNamingStrategy

最后,您可以扩展SpringPhysicalNamingStrategy,然后可以修改该特定的表名。然后,此bean应仅在QA配置文件中处于活动状态。

@Bean
public SpringPhysicalNamingStrategy springPhysicalNamingStrategy() {
    return new SpringPhysicalNamingStrategy() {
        @Override
        public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) {
            // Just change find and replace your table name
            return super.toPhysicalTableName(new Identifier( name.getText(), false), jdbcEnvironment);
        }
    };
}

**另外:只需检查如何为数据库的命名要求构建Identifier