问题描述:自定义拦截器无法兼容分页拦截器,分页的拦截器会在自定义拦截器之前执行
原因:查阅官方拦截器使用文档,发现分页插件的拦截器拦截的是execute类型的过程,是框架最先处理的拦截类型,因此再使用statement类型的拦截不会生效,因为总是在分页的拦截之后,会导致分页count(0)出现sql错误。
解决:将拦截类型都改为execute,并且配置拦截器的时候将自定义拦截器放到分页拦截器后,由于拦截器使用责任链模式还有代理模式,导致最后设置的拦截器会最先执行
解决思路:
1、清楚分页插件拦截的是何种对象,再清楚自己设置的拦截器需要对sql进行什么样的处理。例如修改sql,那么就是要再分页之前先拦截到
2、清楚各类拦截对象的执行顺序
操作步骤:
1、修改sql的拦截器需要拦截Executor,因为涉及到分页插件,为啥可以看下官网的资料,链接在底下。拦截器的intercept方法就用官网的写法
@Intercepts({
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
})
2、手动配置拦截器顺序
@Configuration
public class MybatisPageHelp {
@Autowired
private List<SqlSessionFactory> sqlSessionFactoryList;
/**
* 接受分页插件额外的属性
*
* @return
*/
@Bean
@ConfigurationProperties(prefix = "pagehelper")
public Properties pageHelperProperties() {
return new Properties();
}
@PostConstruct
public void addPageInterceptor() {
SqlIntercept sqlIntercept = new SqlIntercept ();
PageInterceptor pageInterceptor = new PageInterceptor();
Properties properties = new Properties();
//先把一般方式配置的属性放进去
properties.putAll(pageHelperProperties());
//在把特殊配置放进去,由于close-conn 利用上面方式时,属性名就是 close-conn 而不是 closeConn,所以需要额外的一步
pageInterceptor.setProperties(properties);
for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
sqlSessionFactory.getConfiguration().addInterceptor(pageInterceptor);
sqlSessionFactory.getConfiguration().addInterceptor(sqlIntercept );
}
}
}
3、上述配置完会出现系统出现多个插件的报错,在启动类的@SpringBootApplication注解加以下
@SpringBootApplication(exclude = PageHelperAutoConfiguration.class)
拦截器使用文档:官网地址