解决Mybatis自定义拦截器跟分页插件冲突
问题描述:自定义拦截器无法兼容分页拦截器,分页的拦截器会在自定义拦截器之前执行 原因:查阅官方拦截器使用文档,发现分页插件的拦截器拦截的是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)
拦截器使用文档: