標籤:c style class blog code java
Hibernate 使用JPA 對於映射有3種規則可以配置:DefaultNamingStrategy,ImprovedNamingStrategy,EJB3NamingStrategy
這裡只說ImprovedNamingStrategy,其他自行看Hibernate代碼,ImprovedNamingStrategy的代碼如下,是一個singleton instance:
/** Hibernate, Relational Persistence for Idiomatic Java** Copyright (c) 2010, Red Hat Inc. or third-party contributors as* indicated by the @author tags or express copyright attribution* statements applied by the authors. All third-party contributions are* distributed under license by Red Hat Inc.** This copyrighted material is made available to anyone wishing to use, modify,* copy, or redistribute it subject to the terms and conditions of the GNU* Lesser General Public License, as published by the Free Software Foundation.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License* for more details.** You should have received a copy of the GNU Lesser General Public License* along with this distribution; if not, write to:* Free Software Foundation, Inc.* 51 Franklin Street, Fifth Floor* Boston, MA 02110-1301 USA*/package org.hibernate.cfg;import java.io.Serializable;import org.hibernate.util.StringHelper;import org.hibernate.AssertionFailure;/*** An improved naming strategy that prefers embedded* underscores to mixed case names* @see DefaultNamingStrategy the default strategy* @author Gavin King*/public class ImprovedNamingStrategy implements NamingStrategy, Serializable {/** * A convenient singleton instance */public static final NamingStrategy INSTANCE = new ImprovedNamingStrategy();/** * Return the unqualified class name, mixed case converted to * underscores */public String classToTableName(String className) { return addUnderscores( StringHelper.unqualify(className) );}/** * Return the full property path with underscore seperators, mixed * case converted to underscores */public String propertyToColumnName(String propertyName) { return addUnderscores( StringHelper.unqualify(propertyName) );}/** * Convert mixed case to underscores */public String tableName(String tableName) { return addUnderscores(tableName);}/** * Convert mixed case to underscores */public String columnName(String columnName) { return addUnderscores(columnName);}protected static String addUnderscores(String name) { StringBuffer buf = new StringBuffer( name.replace('.', '_') ); for (int i=1; i<buf.length()-1; i++) { if ( Character.isLowerCase( buf.charAt(i-1) ) && Character.isUpperCase( buf.charAt(i) ) && Character.isLowerCase( buf.charAt(i+1) ) ) { buf.insert(i++, '_'); } } return buf.toString().toLowerCase();}public String collectionTableName( String ownerEntity, String ownerEntityTable, String associatedEntity, String associatedEntityTable, String propertyName) { return tableName( ownerEntityTable + '_' + propertyToColumnName(propertyName) );}/** * Return the argument */public String joinKeyColumnName(String joinedColumn, String joinedTable) { return columnName( joinedColumn );}/** * Return the property name or propertyTableName */public String foreignKeyColumnName( String propertyName, String propertyEntityName, String propertyTableName, String referencedColumnName) { String header = propertyName != null ? StringHelper.unqualify( propertyName ) : propertyTableName; if (header == null) throw new AssertionFailure("NamingStrategy not properly filled"); return columnName( header ); //+ "_" + referencedColumnName not used for backward compatibility}/** * Return the column name or the unqualified property name */public String logicalColumnName(String columnName, String propertyName) { return StringHelper.isNotEmpty( columnName ) ? columnName : StringHelper.unqualify( propertyName );}/** * Returns either the table name if explicit or * if there is an associated table, the concatenation of owner entity table and associated table * otherwise the concatenation of owner entity table and the unqualified property name */public String logicalCollectionTableName(String tableName, String ownerEntityTable, String associatedEntityTable, String propertyName) { if ( tableName != null ) { return tableName; } else { //use of a stringbuffer to workaround a JDK bug return new StringBuffer(ownerEntityTable).append("_") .append( associatedEntityTable != null ? associatedEntityTable : StringHelper.unqualify( propertyName ) ).toString(); }}/** * Return the column name if explicit or the concatenation of the property name and the referenced column */public String logicalCollectionColumnName(String columnName, String propertyName, String referencedColumn) { return StringHelper.isNotEmpty( columnName ) ? columnName : StringHelper.unqualify( propertyName ) + "_" + referencedColumn;}}
addUnderscores 用於處理 當表名和列名在Java的種規則符合 UserNameTable(表)和 userNameColumn(列),就會被解析為user_name_table 和 user_name_column ,具體return的處理的是propertyToColumnName。 but呢,如果一旦配置了這個規則,spring +jpa配置如下:
-
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
就會忽略了注釋中的@Column中的name,其實這個name地方就是為了映射資料庫欄位,結果配置了這個就不care了。我去。看下hibernate解釋
https://hibernate.atlassian.net/browse/HHH-8616
覺得是這是一個bug,不知道為啥就這樣fix bug 了。
現在有7-8張表的規則沒有符合這個怎麼辦呢, 重寫了如下。
/** Copyright 2012-2014 sencloud.com.cn. All rights reserved.* Support: http://www.sencloud.com.cn* License: http://www.sencloud.com.cn/license*/package com.sencloud.hibernate.cfg;import java.io.Serializable;import org.hibernate.cfg.ImprovedNamingStrategy;import org.hibernate.cfg.NamingStrategy;import org.hibernate.util.StringHelper;/*** ImprovedNamingStrategy- hibernate映射規則* * @author xutianlong* @version 3.0*/public class MoShopImprovedNamingStrategy extends ImprovedNamingStrategy implements NamingStrategy, Serializable {/** * */private static final long serialVersionUID = 3088474161734101900L;public String propertyToColumnName(String propertyName) { if (propertyName.endsWith("__")) { return propertyName.replace("__", "").toLowerCase(); } return addUnderscores(StringHelper.unqualify(propertyName));}}
改下配置:
<prop key="hibernate.ejb.naming_strategy">com.sencloud.hibernate.cfg.MoShopImprovedNamingStrategy</prop>
那麼怎麼使用這個呢? propertyName必須以 "__"結尾了,然後在規則中統一toLowerCase。 有點那個啥了。
@Column(nullable = false, length=100)private String userName__;