记录一下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中写入表达式即可