问题描述
之前Hibernate中的实体类,对应数据库的字段,例如实体类中驼峰命令是:createDate,对应到数据库是带下划线的:create_date字段,一般来说是需要加@Column特别指定对应数据库表的字段的,例如:
@Column(name = "create_date") public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; }
这样也带来了几个不是很方便的地方:
- 如果类似的字段比较多,创建是类题的字段的工作量比较大
- Hibernate的@Column注解是写在getter上面的,如果你想使用lombok来省略getter和setter,就不行了
所以有必要研究下Hibernate下能否启用自动驼峰命令字段转数据库表的下换线字段的功能。
问题解决
网上都说只要在 application.yml 中增加
spring.jpa.hibernate.properties.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
经过本人测试无效,这个PhysicalNamingStrategyStandardImpl实际就是啥也没有转换
后来这样做才是正确的:
新建Camel2SnakeNamingStrategy.java 实现驼峰转下换线
package com.terrynow.test import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; public class Camel2SnakeNamingStrategy extends PhysicalNamingStrategyStandardImpl { @Override public Identifier toPhysicalCatalogName(final Identifier identifier, final JdbcEnvironment jdbcEnv) { return convertToSnakeCase(identifier); } @Override public Identifier toPhysicalColumnName(final Identifier identifier, final JdbcEnvironment jdbcEnv) { return convertToSnakeCase(identifier); } @Override public Identifier toPhysicalSchemaName(final Identifier identifier, final JdbcEnvironment jdbcEnv) { return convertToSnakeCase(identifier); } @Override public Identifier toPhysicalSequenceName(final Identifier identifier, final JdbcEnvironment jdbcEnv) { return convertToSnakeCase(identifier); } @Override public Identifier toPhysicalTableName(final Identifier identifier, final JdbcEnvironment jdbcEnv) { return convertToSnakeCase(identifier); } private Identifier convertToSnakeCase(final Identifier identifier) { if (identifier == null) { return null; } final String newName = identifier.getText().replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase(); return Identifier.toIdentifier(newName); } }
然后在 Application 中配置:
主要看这句:factoryBean.setPhysicalNamingStrategy(new Camel2SnakeNamingStrategy());//驼峰转下划线实现
其他的根据实际情况修改
/* * Copyright (c) 2021. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.terrynow.test; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; import org.springframework.orm.hibernate5.HibernateTransactionManager; import org.springframework.orm.hibernate5.LocalSessionFactoryBean; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; import java.util.Properties; //@EnableDiscoveryClient // 排除 DataSource, JPARepositories, HibernateJpa 的自动配置 @SpringBootApplication(exclude = { // DataSourceAutoConfiguration.class, JpaRepositoriesAutoConfiguration.class, HibernateJpaAutoConfiguration.class}) // 开启事务管理 @EnableTransactionManagement(proxyTargetClass = true) public class MyApplication { @Autowired private Environment env; public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } @Autowired @Bean(name = "sessionFactory") public SessionFactory getSessionFactory(DataSource dataSource) throws Exception { LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean(); // Package contain entity classes factoryBean.setPackagesToScan("com.terrynow.test.entity"); factoryBean.setDataSource(dataSource); factoryBean.setPhysicalNamingStrategy(new Camel2SnakeNamingStrategy());//驼峰转下划线实现 factoryBean.afterPropertiesSet(); return factoryBean.getObject(); } @Autowired @Bean(name = "transactionManager") public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) { return new HibernateTransactionManager(sessionFactory); } }
如果是普通SpringMVC项目整合Hibernate5启用实体类驼峰命令转数据库表字段下划线实现,也做类似的配置,详见:https://blog.terrynow.com/2022/05/02/springmvc-hibernate-auto-convert-pojo-camel-to-underline-strategy/
文章评论