配置Hibernate Dialect的最佳方法

4,409 阅读2分钟

简介

在这篇文章中,我将解释什么是配置Hibernate Dialect的最佳方式,这样你就能从数据库中获得最大的收益。

手动解决Hibernate方言

传统上,用户必须通过hibernate.dialect 设置提供HibernateDialect

因此,如果你使用MySQL 8,你将在application.properties Spring Boot配置文件中提供以下设置。

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

或者,如果你使用与MySQL 5.7兼容的Aurora MySQL版本2,那么你就必须设置MySQL57Dialect ,正如本文所解释的。

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect

这种方法的缺点是,当迁移到与MySQL 8兼容的Amazon Aurora MySQL 3时,我们必须记得更新hibernate.dialect 的设置。

自动解决Hibernate方言

因此,在Hibernate 6中得到明显改进的更好的方法是自动方言解析,它看起来如下。

Hibernate Dialect Resolution

在启动时,Hibernate可以从JDBC驱动中提取 DatabaseMetaData从JDBC驱动中提取并使用它来创建 DialectResolutionInfo它同时封装了数据库服务器版本和JDBC驱动客户端版本。

有了DialectResolutionInfo ,Hibernate就可以根据底层数据库服务器和客户端的能力来挑选合适的方言并配置其行为。

例如,在Hibernate 6中,MySQLDialect ,根据底层MySQL数据库服务器版本配置最大VARCHARVARBINARY列的长度。

public MySQLDialect(
        DialectResolutionInfo info) {
        
    super( info );
    
    int bytesPerCharacter = getCharacterSetBytesPerCharacter(
        info.getDatabaseMetadata()
    );
    
    maxVarcharLength = maxVarcharLength( 
        getMySQLVersion(), 
        bytesPerCharacter 
    );
    
    maxVarbinaryLength = maxVarbinaryLength( 
        getMySQLVersion() 
    );
}

private static int maxVarcharLength(
        DatabaseVersion version, 
        int bytesPerCharacter) {
    // max length for VARCHAR changed in 5.0.3
    if (version.isBefore(5)) {
        return 255;
    }
    else {
        switch (bytesPerCharacter) {
            case 1:
                return 65_535;
            case 2:
                return 32_767;
            case 3:
                return 21_844;
            case 4:
            default:
                return 16_383;
        }
    }
}

private static int maxVarbinaryLength(
        DatabaseVersion version) {
    return version.isBefore(5) ? 255 : 65_535;
}

Hibernate 6方言选项

在Hibernate 6之前,HibernateDialect 选项已经泛滥成灾,而且Hibernate Spatial项目已经并入Hibernate,这使得事情变得更加糟糕,如下图所示。

Hibernate 6 MySQL Dialect

幸运的是,在Hibernate 6中,你不再需要推理在你也采用空间列的情况下应该使用MySQL57Dialect 还是MySQL56InnoDBSpatialDialect ,因为仅仅是MySQLDialect 就可以处理各种口味的各种MySQL版本。

很酷,对吗?

总结

虽然在Hibernate 6之前,通过hibernate.dialect 设置提供Dialect 版本是很常见的,但这已不再是推荐的策略。

因为Hibernate 6极大地简化了Dialect 处理程序,最好让Hibernate根据底层数据库服务器和客户端的能力来决定使用什么Dialect 实例。