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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM