Shellbye.github.io
Shellbye.github.io copied to clipboard
Spring Boot JPA Hibernate 添加表名前缀 table name prefix
在JPA
和Hibernate
的帮助下,Spring
用起来也和Django
很像,可以自动的从model
生成数据库表。我最近在项目中遇到一个需要给所有的表都加一个tb_
的前缀,从网上找了找,果然可以做到,下面简单记录一下。
本项目的整个工程链接在Github,下面是最核心的文件PrefixTbNamingStrategy.class
package com.example.demo;
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;
import java.util.Locale;
@Configuration
public class PrefixTbNamingStrategy implements PhysicalNamingStrategy {
@Override
public Identifier toPhysicalCatalogName(Identifier name,
JdbcEnvironment jdbcEnvironment) {
return apply(name, jdbcEnvironment);
}
@Override
public Identifier toPhysicalSchemaName(Identifier name,
JdbcEnvironment jdbcEnvironment) {
return apply(name, jdbcEnvironment);
}
@Override
public Identifier toPhysicalTableName(Identifier name,
JdbcEnvironment jdbcEnvironment) {
Identifier identifier = apply(name, jdbcEnvironment);
String tbName = "tb_" + identifier.toString();
return new Identifier(tbName, identifier.isQuoted());
}
@Override
public Identifier toPhysicalSequenceName(Identifier name,
JdbcEnvironment jdbcEnvironment) {
return apply(name, jdbcEnvironment);
}
@Override
public Identifier toPhysicalColumnName(Identifier name,
JdbcEnvironment jdbcEnvironment) {
return apply(name, jdbcEnvironment);
}
private Identifier apply(Identifier name, JdbcEnvironment jdbcEnvironment) {
if (name == null) {
return null;
}
StringBuilder builder = new StringBuilder(name.getText().replace('.', '_'));
for (int i = 1; i < builder.length() - 1; i++) {
if (isUnderscoreRequired(builder.charAt(i - 1), builder.charAt(i),
builder.charAt(i + 1))) {
builder.insert(i++, '_');
}
}
return getIdentifier(builder.toString(), name.isQuoted(), jdbcEnvironment);
}
/**
* Get an identifier for the specified details. By default this method will return an
* identifier with the name adapted based on the result of
* {@link #isCaseInsensitive(JdbcEnvironment)}
*
* @param name the name of the identifier
* @param quoted if the identifier is quoted
* @param jdbcEnvironment the JDBC environment
* @return an identifier instance
*/
protected Identifier getIdentifier(String name, boolean quoted,
JdbcEnvironment jdbcEnvironment) {
if (isCaseInsensitive(jdbcEnvironment)) {
name = name.toLowerCase(Locale.ROOT);
}
return new Identifier(name, quoted);
}
/**
* Specify whether the database is case sensitive.
*
* @param jdbcEnvironment the JDBC environment which can be used to determine case
* @return true if the database is case insensitive sensitivity
*/
protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) {
return true;
}
private boolean isUnderscoreRequired(char before, char current, char after) {
return Character.isLowerCase(before) && Character.isUpperCase(current)
&& Character.isLowerCase(after);
}
}
这个文件基本上copy自org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
,只在方法toPhysicalTableName
上做了一个最简单的修改,实现了想要的功能。代码应该是还可以进一步精简的(比如直接继承SpringPhysicalNamingStrategy
),但是这里只是记录一种思路,就不进行精简了。
这里要特别说明一下顶部的注解@Configuration
,如果不加这个注解,就需要在application.properties
里面添加如下一行
spring.jpa.hibernate.naming.physical-strategy=com.example.demo.PrefixTbNamingStrategy