dynamic-pagehelper-auto-dialect

动态 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);
    }
}
2024年3月6日