最近升级项目中的jpa到2.*版本,Hibernate也升级至Hibernate5发现配置"hibernate.ejb.naming_strategy"无效,
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
原来的实体类中以驼峰命名的列名与数据库交互时无法自动转化为_,例如:
loginName -> login_name
网上搜了下Hibernate5中自定义实体类与数据库命名规则的方法相比之前版本有较大改变,已不支持"hibernate.ejb.naming_strategy",hibernate5改为通过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来做扩展
只需要重写determineBasicColumnName(ImplicitBasicColumnNameSource source)方法即可实现改变列名命名规则
话不多说,上代码:
public class ImplicitNamingStrategy extends ImplicitNamingStrategyJpaCompliantImpl implements Serializable {
private static final long serialVersionUID = 4640609569880788472L;
@Override
public Identifier determineBasicColumnName(ImplicitBasicColumnNameSource source) {
String name = addUnderscores(transformAttributePath(source.getAttributePath()));
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();
}
}


发布评论