动态 PageHelper AutoDialect 方案 #
配置 #
yml
pagehelper:
# 是否运行时自动识别方言。多种数据库类型的多数据源环境下需要开启此选项,否则可能会导致分页出错。
autoRuntimeDialect: true
# 配置自动识别方言实现类
autoDialectClass: com.example.datasource.pagehelper.DynamicAutoDialect
Java代码 #
java
package com.example.datasource.pagehelper;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.github.pagehelper.dialect.auto.DataSourceNegotiationAutoDialect;
import org.apache.ibatis.mapping.MappedStatement;
import javax.sql.DataSource;
import java.util.Properties;
/**
* PageHelper分页插件-动态数据源自动识别方言实现类
* <pre>
* 自动识别方言(AutoDialect)的核心逻辑:
* 先根据 MappedStatement 获取 DataSource,再获取 DataSource 的链接地址,最后根据链接地址前缀返回相应数据库方言。
*
* 如果 DataSource 是插件内部(DataSourceNegotiationAutoDialect)配置好的常见数据源类型,则会直接返回链接地址;
* 否则会先获取连接对象,然后获取元信息取出其中的链接地址,这样会影响性能。
*
* 因此,对于动态数据源,不建议使用默认的 AutoDialect,而是手动实现并添加到配置(pagehelper.autoDialectClass)。
* </pre>
*
* @author jiahui156
* @see com.github.pagehelper.AutoDialect 自动识别方言
* @see com.github.pagehelper.dialect.auto.DataSourceNegotiationAutoDialect 遍历数据源自动方言实现类
* @see com.baomidou.dynamic.datasource.DynamicRoutingDataSource 动态数据源
* @since 2024-03-05
*/
public class DynamicAutoDialect extends DataSourceNegotiationAutoDialect {
@Override
public String extractDialectKey(MappedStatement ms, DataSource dataSource, Properties properties) {
// 若是动态数据源,则先确定实际使用的数据源是哪个
DataSource realDataSource = dataSource;
while (realDataSource instanceof DynamicRoutingDataSource) {
realDataSource = ((DynamicRoutingDataSource) dataSource).determineDataSource();
}
return super.extractDialectKey(ms, realDataSource, properties);
}
}