Spring Boot JPA 将模式名称外部化为属性文件
Posted
技术标签:
【中文标题】Spring Boot JPA 将模式名称外部化为属性文件【英文标题】:Spring Boot JPA externalizing the schema name to property file 【发布时间】:2019-04-29 13:09:05 【问题描述】:我的 Spring Boot 应用程序有 2 个模式,我像这样在 Entity 类中对其进行硬编码
@Entity
@Table(name"TABLE_NAME_1", schema="SCHEMA_NAME_1")
public class EntityName1
...
@Entity
@Table(name"TABLE_NAME_2", schema="SCHEMA_NAME_2")
public class EntityName2
...
问题是这个模式名称在每个版本中都会不断变化。因此,每次发布后,我们都必须到这里来对实体文件的架构名称进行必要的更改。
现在我想我们可以在 Spring Boot 中配置 default_schema 但这不起作用,因为我们需要将两个模式名称都外部化。
有什么方法可以使用这样的东西: @实体 @Table(name"TABLE_NAME_1", schema="default.schema_1") 公共类 EntityName1 ...
@Entity
@Table(name"TABLE_NAME_2", schema="default.schema_2")
public class EntityName2
...
我们在外部文件中定义 default.schema_1 和 default.schema_2。
【问题讨论】:
Change database schema used by Spring Boot的可能重复 这就是为什么 JPA 允许您将 SCHEMA 信息放入orm.xml
然后您只需更新该映射文件,而不是将其全部静态硬编码到需要重新编译的类中的原因之一!
【参考方案1】:
请试试这个...
-
创建类 SystemProps
public class SystemProps
private static Map<String,String> props = null;
public static void loadPropsAll()
props = new HashMap<>();
File file = null;
try
file = ResourceUtils.getFile("classpath:application.properties");
loadProps(file,props);
String x = SystemProperties.get("spring.profiles.active");
if(x != null)
file = ResourceUtils.getFile("classpath:application-" + x + ".properties");
loadProps(file, props);
catch (Exception e)e.printStackTrace();finally
private static void loadProps(File file, Map<String,String> props)
BufferedReader br = null;
try
br = new BufferedReader(new FileReader(file));
while (br.ready())
String line = br.readLine();
System.out.println(line);
if(!line.startsWith("#") && line.indexOf("=")!=-1)
props.put(""+line.split("=")[0].trim(), line.split("=")[1].trim());
catch (Exception e)
e.printStackTrace();
finally
try
br.close();
catch (IOException e)
e.printStackTrace();
public static String getProp(String name)
if(props==null)
loadPropsAll();
return props.get(name);
-
为 jpa 创建自定义命名策略
public class CustomPhysicalNamingStrategy extends SpringPhysicalNamingStrategy
@Override
public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironment)
if(name.getText().startsWith("$"))
String x = name.getText().replace("$","").replaceAll("\\","").replaceAll("","");
String schema = SystemProps.getProp(x);
return super.toPhysicalSchemaName(new Identifier(schema,name.isQuoted()), jdbcEnvironment);
return super.toPhysicalSchemaName(name, jdbcEnvironment);
-
在 application.properties 文件中添加属性...
spring.jpa.hibernate.naming.physical-strategy=my.package.CustomPhysicalNamingStrategy
my_schema_name_property=SCHEMA_NAME_2
现在可以使用了
@Entity
@Table(name"TABLE_NAME_1", schema="$my_schema_name_property")
public class EntityName1
...
【讨论】:
【参考方案2】:您只能通过反射在运行时更改模式的值(或任何其他注释值)。例如如何做到这一点看here。
然后您可以创建一个实现 ApplicationListener<ApplicationReadyEvent>
的 bean,该 bean 将执行 onApplicationEvent
方法,在您的情况下,该方法将在您的应用程序启动后更改特定实体类的架构值。
【讨论】:
以上是关于Spring Boot JPA 将模式名称外部化为属性文件的主要内容,如果未能解决你的问题,请参考以下文章
具有多个数据源和外部配置的 Spring Boot,Spring JPA
添加spring boot jpa依赖项时创建名称为“entityManagerFactory”的bean时出错
将实体分配给持久性单元(spring-boot,spring-data-jpa)