admin管理员组

文章数量:1530842

最近升级项目中的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();
    }
}

本文标签: HibernatenamingstrategyEJB