随笔 - 832  文章 - 2  评论 - 31  阅读 - 167万

Hibernate数据库配置项中命名策略说明

一、Hibernate5之前

命名策略采用naming-strategy配置项

spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.DefaultNamingStrategy

1、配置值org.hibernate.cfg.DefaultNamingStrategy

hibernate默认配置,采用直接映射的方式,不会做过多的处理,当然前提是没有使用@Table和@Column注解,如果有则以注解内容为准。

2、配置值org.hibernate.cfg.ImprovedNamingStrategy

表名,字段为小写,当有大写字母的时候会添加下划线分隔符号,如:user_id。

二、Hibernate5之后

采用implicit-strategy和physical-strategy两个配置项分别控制命名策略

    spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
    spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

1、implicit-strategy和physical-strategy的区别

(1)、implicit-strategy负责模型对象层次的处理,将对象模型处理为逻辑名称。physical-strategy负责映射成真实的数据名称的处理,将上述的逻辑名称处理为物理名称。

(2)、当没有使用@Table和@Column注解时,implicit-strategy配置项才会被使用,当对象模型中已经指定时,implicit-strategy并不会起作用。physical-strategy一定会被应用,与对象模型中是否显式地指定列名或者已经被隐式决定无关。

2、implicit-strategy逻辑名称命名策略

有五个配置值

    org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
    org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl
    org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl
    org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
    org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy

默认为ImplicitNamingStrategyJpaCompliantImpl,后四者均继承自它。

3、physical-strategy物理名称命名策略

有两个配置值:

 默认为SpringPhysicalNamingStrategy

    #直接映射,不会做过多的处理
    org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    #表名,字段为小写,当有大写字母的时候会添加下划线分隔符号
    org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy

 

 

 

 

复制代码
/*
 * Copyright 2012-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 org.springframework.boot.orm.jpa.hibernate;

import java.util.Locale;

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

/**
 * Hibernate {@link PhysicalNamingStrategy} that follows Spring recommended naming
 * conventions.
 *
 * @author Phillip Webb
 * @author Madhura Bhave
 * @since 1.4.0
 */
public class SpringPhysicalNamingStrategy implements PhysicalNamingStrategy {

    @Override
    public Identifier toPhysicalCatalogName(Identifier name,
            JdbcEnvironment jdbcEnvironment) {
        return apply(name, jdbcEnvironment);
    }

    @Override
    public Identifier toPhysicalSchemaName(Identifier name,
            JdbcEnvironment jdbcEnvironment) {
        return apply(name, jdbcEnvironment);
    }

    @Override
    public Identifier toPhysicalTableName(Identifier name,
            JdbcEnvironment jdbcEnvironment) {
        return apply(name, jdbcEnvironment);
    }

    @Override
    public Identifier toPhysicalSequenceName(Identifier name,
            JdbcEnvironment jdbcEnvironment) {
        return apply(name, jdbcEnvironment);
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier name,
            JdbcEnvironment jdbcEnvironment) {
        return apply(name, jdbcEnvironment);
    }

    private Identifier apply(Identifier name, JdbcEnvironment jdbcEnvironment) {
        if (name == null) {
            return null;
        }
        StringBuilder builder = new StringBuilder(name.getText().replace('.', '_'));
        for (int i = 1; i < builder.length() - 1; i++) {
            if (isUnderscoreRequired(builder.charAt(i - 1), builder.charAt(i),
                    builder.charAt(i + 1))) {
                builder.insert(i++, '_');
            }
        }
        return getIdentifier(builder.toString(), name.isQuoted(), jdbcEnvironment);
    }

    /**
     * Get an identifier for the specified details. By default this method will return an
     * identifier with the name adapted based on the result of
     * {@link #isCaseInsensitive(JdbcEnvironment)}
     * @param name the name of the identifier
     * @param quoted if the identifier is quoted
     * @param jdbcEnvironment the JDBC environment
     * @return an identifier instance
     */
    protected Identifier getIdentifier(String name, boolean quoted,
            JdbcEnvironment jdbcEnvironment) {
        if (isCaseInsensitive(jdbcEnvironment)) {
            name = name.toLowerCase(Locale.ROOT);
        }
        return new Identifier(name, quoted);
    }

    /**
     * Specify whether the database is case sensitive.
     * @param jdbcEnvironment the JDBC environment which can be used to determine case
     * @return true if the database is case insensitive sensitivity
     */
    protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) {
        return true;
    }

    private boolean isUnderscoreRequired(char before, char current, char after) {
        return Character.isLowerCase(before) && Character.isUpperCase(current)
                && Character.isLowerCase(after);
    }

}
复制代码

3、自定义命名策略  

  a、实现PhysicalNamingStrategy接口

  b、重写PhysicalNamingStrategy接口中的方法,比如将所有表名及表中都加上相同的前缀yd_

复制代码
package springdatajpa.config;

import java.io.Serializable;
import java.util.Locale;

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

public class JpaNameStrategy implements PhysicalNamingStrategy,Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    
    private static final String PREFIX="yd_";

    public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        // TODO Auto-generated method stub
        return null;
    }

    public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        // TODO Auto-generated method stub
        return null;
    }

    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        if(name==null) {
            return null;
        }else {
            String nameText=PREFIX+name.getText();
            StringBuilder sb=new StringBuilder(nameText.replace(".", "-"));
            return this.getIdentifier(nameText.toString(), name.isQuoted(), jdbcEnvironment);
        }
        
    }

    public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        
        return null;
    }

    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        if(name==null) {
            return null;
        }else {
            String nameText=PREFIX+name.getText();
            StringBuilder sb=new StringBuilder(nameText.replace(".", "-"));
            return this.getIdentifier(nameText.toString(), name.isQuoted(), jdbcEnvironment);
        }
    }
    
     protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) {
            return true;
        }
    
    protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
        if (this.isCaseInsensitive(jdbcEnvironment)) {
            name = name.toLowerCase(Locale.ROOT);
        }

        return new Identifier(name, quoted);
    }

}
复制代码

application.properties配置

spring.jpa.hibernate.naming.physical-strategy=springdatajpa.config.JpaNameStrategy

 

 

 

 

 

 

可参考:

Hibernate中实体映射时的命名策略(1)

Hibernate中实体映射时的命名策略(2)

posted on   小破孩楼主  阅读(1443)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示