【问题标题】:Setting @Table in run time Spring在运行时设置@Table Spring
【发布时间】:2018-11-02 20:26:22
【问题描述】:

我正在编写一个 spring 服务来使用 JPA 连接到我的 PostgreSQL SQL 服务器。我面临的问题是如何在运行时将 @Table 设置为一个值。我有两张桌子,一张用于 QA,另一张用于 prod。因此,当我执行 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 的配置文件设置。

【问题讨论】:

  • 这就是JPA规范定义orm.xml的原因...

标签: spring hibernate jpa


【解决方案1】:

您有三个选择:

orm.xml(推荐)

您可以定义一个 orm.xml。使用它,您可以覆盖实体的表名。 通常你会把 orm.xml 放到你的 resources/META-INF 文件夹中。但这将适用于您的所有配置文件,因为 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);
        }
    };
}

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

【讨论】:

    猜你喜欢
    • 2015-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多