Hibernate5 ImplicitNamingStrategy与PhysicalNamingStrategy

Hibernate5中自定义实体类与数据库命名规则的方法相比之前版本有较大改变,在hibernate5之前的版本实现NamingStrategy就可以实现自定义规则,hibernate5改为通过ImplicitNamingStrategy与PhysicalNamingStrategy实现。

关于ImplicitNamingStrategy与PhysicalNamingStrategy详细的解释可以看官方文档,也可以参考其它博文,这里不在详述,参考博文:Hibernate入门之命名策略(naming strategy)详解

简单介绍一下ImplicitNamingStrategy与PhysicalNamingStrategy

ImplicitNamingStrategy:隐式规则,如果实体类没有@Entity(name = "table_xxx")或@Column(name="column_xxx")等指定数据库表名或列名的话,ImplicitNamingStrategy有效,如果在注解中指定名称,则以注解为准。

PhysicalNamingStrategy:物理规则,不管有没有@Entity(name = "table_xxx")或@Column(name="column_xxx")等注解命名,都要按自定义的PhysicalNamingStrategy规则映射数据库名称。

下面用示例来说明实际使用方法

需求一:为了统一命名规范,强制要求数据库映射实体类属性字段使用驼峰命名,数据库字段使用下划线_命名,而又不想麻烦在实体类每个属性上都加上@Column(name="column_xxx")注解,而是没有注解的根据属性名自动映射数据库字段,有注解的则使用注解的名称映射,那么应该使用ImplicitNamingStrategy。

hibernate已经提供了多个ImplicitNamingStrategy的实现,我们基于其中一个实现ImplicitNamingStrategyJpaCompliantImpl来做扩展

public class MyImplicitNamingStrategy extends ImplicitNamingStrategyJpaCompliantImpl {

	private static final long serialVersionUID = 1l;

	@Override
	public Identifier determineJoinTableName(ImplicitJoinTableNameSource source) {
		String name = source.getOwningPhysicalTableName() + "_"
				+ source.getAssociationOwningAttributePath().getProperty();
		return toIdentifier(name, source.getBuildingContext());
	}

	/**
	 * 重写此方法实现,驼峰转_
	 */
	@Override
	public Identifier determineBasicColumnName(ImplicitBasicColumnNameSource source) {
		String name = transformAttributePath( source.getAttributePath() );
		name = addUnderscores(name);
		return toIdentifier( name, source.getBuildingContext() );
	}
	
	protected static String addUnderscores(String name) {
		StringBuilder buf = new StringBuilder( 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(Locale.ROOT);
	}
}

只需要重写determineBasicColumnName(ImplicitBasicColumnNameSource source)方法即可实现改变列名命名规则

 

需求二:统一管理数据库表的前缀与后缀,如果在每个@Entity(name = "table_xxx")中都加上前后缀,会比较麻烦切不便于统一管理,那么可以通过自定义PhysicalNamingStrategy实现

hibernate依然提供了多个PhysicalNamingStrategy的实现,我们基于其中的PhysicalNamingStrategyStandardImpl来实现需求

public class MyPhysicalNamingStrategy extends PhysicalNamingStrategyStandardImpl {
	private static final long serialVersionUID = 1l;
	
	/**
	 * 数据库表前缀
	 */
	private String prefix;
	
	/**
	 * 数据库表后缀
	 */
	private String suffix;
	
	/**
	 * 数据库表前缀
	 */
	public String getPrefix() {
		return prefix;
	}

	/**
	 * 数据库表前缀
	 */
	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}

	/**
	 * 数据库表后缀
	 */
	public String getSuffix() {
		return suffix;
	}

	/**
	 * 数据库表后缀
	 */
	public void setSuffix(String suffix) {
		this.suffix = suffix;
	}

    /**
	 * 重写方法实现自动追加前缀后缀
	 */
	@Override
	public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
		StringBuilder nameSB = new StringBuilder();
		if(!StringUtils.isEmpty(prefix)) {
			nameSB.append(prefix);
		}
		nameSB.append(name.getText());
		if(!StringUtils.isEmpty(suffix)) {
			nameSB.append(suffix);
		}
		
		return new Identifier(nameSB.toString(), name.isQuoted());
	}
}

重写toPhysicalTableName方法即可实现对表名的规则定制

 

使用方法

<bean id="sessionFactory"
		class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">

		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
				<prop key="hibernate.default_batch_fetch_size">16</prop>
			</props>
		</property>
		<property name="implicitNamingStrategy" ref="myImplicitNamingStrategy" />
		<property name="physicalNamingStrategy" ref="myPhysicalNamingStrategy" />
	</bean>

    <!-- 这里是自定义的两个类的bean -->
	<bean id="myImplicitNamingStrategy" 
		class="com.test.MyImplicitNamingStrategy"/>
	<bean id="myPhysicalNamingStrategy" 
		class="com.test.MyPhysicalNamingStrategy">
		<property name="prefix" value="u_"/>
		<property name="suffix" value="_s"/>
	</bean>

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值