記錄一下hibernate動態設置表名的一些坑
首先maven引入等不貼了,到這一步,一般來說,maven肯定引入了
首先需要自定義一個類,主要用來解析表達式
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.expression.BeanFactoryAccessor;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.expression.Expression;
import org.springframework.expression.ParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
/**
* 自定義命名策略(實現支持解析#{javaConfig.property}獲取表名功能 )
*
* @author Java大笨笨
* @since 2019-03-26
*/
@Component
public class MySpringPhysicalNamingStrategy extends PhysicalNamingStrategyStandardImpl
implements ApplicationContextAware {
private final StandardEvaluationContext context = new StandardEvaluationContext();
private final SpelExpressionParser parser = new SpelExpressionParser();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context.addPropertyAccessor(new BeanFactoryAccessor());
this.context.setBeanResolver(new BeanFactoryResolver(applicationContext));
this.context.setRootObject(applicationContext);
}
@Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) {
String nameStr = name.getText();
if(nameStr.contains(ParserContext.TEMPLATE_EXPRESSION.getExpressionPrefix())){
//參考SimpleElasticsearchPersistentEntity 實現思想,將tableName參數的值支持表達式獲取
Expression expression = this.parser.parseExpression(nameStr, ParserContext.TEMPLATE_EXPRESSION);
return Identifier.toIdentifier((String)expression.getValue(this.context, String.class));
}else {
//默認方式不變
return super.toPhysicalTableName(name, jdbcEnvironment);
}
}
}
注意,這個類要繼承一個PhysicalNamingStrategyStandardImpl,這個取決於你目前項目中的naming.physical-strategy,我之前用的是PhysicalNamingStrategyStandardImpl,所以這里繼承並重新toPhysicalTableName方法。
yml配置
spring:
jpa:
database: mysql
show-sql: true
hibernate:
ddl-auto: none
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
properties:
hibernate.format_sql: false
hibernate.naming.physical-strategy: xxxxx你的包名.MySpringPhysicalNamingStrategy
hibernate.cache.use_second_level_cache: false
hibernate.search.default.directory_provider: filesystem
hibernate.search.default.indexBase: c:\\xxxx
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @author java大笨笨
* @create 2021-02-23 16:07
*/
@Component("optionsConfig")
public class OptionsConfig {
@Value("${site.options.table_name}")
private String optionsTableName;
public String getOptionsTableName() {
return optionsTableName;
}
public void setOptionsTableName(String optionsTableName) {
this.optionsTableName = optionsTableName;
}
}
注意@Component("optionsConfig"),給個名字,否則會在表達式解析時候找不到這個類
*/
@Entity
@Table(name = "#{optionsConfig.optionsTableName}")
public class Options {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
…………
最后這樣,在name中寫入表達式即可
