記錄一下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中寫入表達式即可