Spring/SpringBoot下Hibernate开启字段驼峰命名转数据库字段下划线

2022-04-22 1384点热度 0人点赞 0条评论

问题描述

之前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/

admin

这个人很懒,什么都没留下

文章评论

您需要 登录 之后才可以评论