Java Hibernate@Table注释中的动态模式
假设您在两个环境中有四个MySQL数据库模式:Java Hibernate@Table注释中的动态模式,java,hibernate,Java,Hibernate,假设您在两个环境中有四个MySQL数据库模式: foo(产品数据库) bar(正在对foodb进行重组) foo_beta(测试数据库) 和bar_beta(新结构的测试数据库) 此外,假设您有一个在实体上带有Hibernate注释的Spring Boot应用程序,如下所示: @Table(name="customer", schema="bar") public class Customer { ... } @Table(name="customer", schema="foo") pu
(产品数据库)foo
(正在对bar
db进行重组)foo
(测试数据库)foo_beta
- 和
(新结构的测试数据库)bar_beta
@Table(name="customer", schema="bar")
public class Customer { ... }
@Table(name="customer", schema="foo")
public class LegacyCustomer { ... }
在本地开发时,这没有问题。您可以在本地环境中模拟生产数据库表名。但是,您尝试在功能上线之前演示它,并希望将其上载到服务器。在另一个端口上启动应用程序的另一个实例,并意识到此副本需要指向“foo_beta”和“bar_beta”,而不是“foo”和“bar”!怎么办
如果您在应用程序中只使用一个模式,那么您可以将所有模式都省略,并指定hibernate.default\u schema
,但是。。。你用了两个。那就完了
--e、 g.
@Table(name=“customer”,schema=“${myApp.schemaName}”)
不是一个选项——(甚至有些傲慢的“没人需要这个”注释),所以如果动态定义模式是荒谬的,那我们该怎么办?除此之外,您知道,一开始就没有进入这种荒谬的场景。您可以使用orm.xml文件覆盖在注释中声明的设置。配置maven或任何用于生成可部署构建构件的工具,以便为测试环境创建覆盖文件。我通过向Hibernate添加对我自己的模式注释的支持,解决了此类问题。通过扩展LocalSessionFactoryBean
(或者对于hibernate3的AnnotationSessionFactoryBean
)来实现并不困难。注释如下所示
@Target(TYPE)
@Retention(RUNTIME)
public @interface Schema {
String alias() default "";
String group() default "";
}
使用示例
@Entity
@Table
@Schema(alias = "em", group = "ref")
public class SomePersistent {
}
spring配置中指定了
别名
和组
的每个组合的架构名称。您可以尝试使用拦截器
public class CustomInterceptor extends EmptyInterceptor {
@Override
public String onPrepareStatement(String sql) {
String prepedStatement = super.onPrepareStatement(sql);
prepedStatement = prepedStatement.replaceAll("schema", "Schema1");
return prepedStatement;
}
}
在会话对象中添加此拦截器作为
Session session = sessionFactory.withOptions().interceptor(new MyInterceptor()).openSession();
因此,当执行ever onPrepareStatement时,将调用此代码块,并将架构名称从schema更改为schema1。这解决了我的问题,了解更多信息