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)

猜你喜欢

转载自www.cnblogs.com/zouhong/p/13406643.html