mybatis-pagehelper-with-multiple-datasource

mybatis pagehelper 多数据源分页,要关闭PageHelperAutoConfiguration。

背景

系统中接入了mysql和postgres,使用mybatis作为ORM框架。需要支持分页,使用pagehelper插件。

区分不同的数据源配置

不同数据库分页格式不一样。因此要针对不同的数据库配置pagehelper。 因为有多个数据源,SqlSessionFactory、 DataSourceTransactionManager、 SqlSessionTemplate、 JdbcTemplate 等类要使用@Qualifier分别注入。

@Bean(name = "pgSqlSessionFactory")
public SqlSessionFactory pgSqlSessionFactory(@Qualifier("pgDataSource") DataSource dataSource) throws Exception {
    SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
    bean.setDataSource(dataSource);
    org.apache.ibatis.session.Configuration Configuration = new org.apache.ibatis.session.Configuration();
    boolean mapUnderscoreToCamelCase = false;
    if ("TRUE".equals(mapUnderscoreToCamelCase.toUpperCase())) {
        mapUnderscoreToCamelCase = true;
    }
    // 注意这里是PageInterceptor的拦截器,此处有伏笔
    Interceptor interceptor = new PageInterceptor();
    Properties properties = new Properties();
    //数据库,分页配置
    properties.setProperty("helperDialect", "postgresql");
    //是否分页合理化
    properties.setProperty("reasonable", "false");
    interceptor.setProperties(properties);
    bean.setPlugins(new Interceptor[] {interceptor});
    Configuration.setMapUnderscoreToCamelCase(mapUnderscoreToCamelCase);
    bean.setConfiguration(Configuration);
    bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocation));
    return bean.getObject();
}

@Bean(name = "pgJdbcTemplate")
public JdbcTemplate pgJdbcTemplate(@Qualifier("pgDataSource") DataSource dataSource) throws Exception {
    return new JdbcTemplate(dataSource);
}

方言列表见 PageAutoDialect

解决:“在系统中发现了多个分页插件”

直接启动没问题,但是真正查询的时候报错:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.RuntimeException: 在系统中发现了多个分页插件,请检查系统配置!

pagehelper插件通过pagehelper-spring-boot-starter依赖引入。 会自动引入PageHelperAutoConfiguration自动配置类:

@Bean
@ConfigurationProperties(prefix = PageHelperProperties.PAGEHELPER_PREFIX)
public Properties pageHelperProperties() {
    return new Properties();
}

@PostConstruct
public void addPageInterceptor() {
    PageInterceptor interceptor = new PageInterceptor();
    Properties properties = new Properties();
    //先把一般方式配置的属性放进去
    properties.putAll(pageHelperProperties());
    //在把特殊配置放进去,由于close-conn 利用上面方式时,属性名就是 close-conn 而不是 closeConn,所以需要额外的一步
    properties.putAll(this.properties.getProperties());
    interceptor.setProperties(properties);
    for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
        sqlSessionFactory.getConfiguration().addInterceptor(interceptor);
    }
}

因为原来配置文件已经有pagehelper:

pagehelper:
  helperDialect: mysql
  reasonable: true
  supportMethodsArguments: true
  params: count=countSql

导致加入了2个PageInterceptor。

解决方法:

  • 屏蔽掉 PageHelperAutoConfiguration,同时删除多余配置
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, PageHelperAutoConfiguration.class})
Built with Hugo
Theme Stack designed by Jimmy