写在前面 在一个大系统里面,因为开发风格的不同,可能会导致有时候会有多种不同配置问题,如果你在确保其他配置都没有问题的情况下,再来本文寻找答案。
使用背景
一般我们的分页实现可能是使用开源的分页框架MybatisPageHelper
,或者是自己定义的分页操作又或者使用的是mybatis-plus自带的分页操作等等,如果是单独的一种可能没有什么问题,但是如果我们要混合使用就有可能出现拦截器被挤掉的情况,导致最后无法使用这一种拦截等问题,这篇文章带你了解各种bug如何解决
案例描述一:在原有的项目中只有mybatis需要新添加mybatis-plus
我司需要在原先只有mybatis的基础上进行升级,加入
mybatis-plus
提升开发效率,但是在我加入mybatis-plus之后会报异常,提示找不到mybatis-plus
里面的方法.
如下错误:
Invalid bound statement (not found):你调用的mybatis-plus里面的各种方法
这里在你检查了其他配置都没有问题的情况下,你尝试看看项目里面有没有自定义的MyBatisConfig
如果有那么就非常有可能是这里有问题了,我们找到
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception{
// 实际注入情况
}
在找到这个方法之后,然后我们修改里面的内容
// 比如最后return的里面的内容是如下内容
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
return sessionFactory.getObject();
我们修改MybatisSqlSessionFactoryBean
之后再次重启实验
final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
return sessionFactory.getObject();
案例描述二:分页冲突
比如在我的项目里面就同时用了
MybatisPageHelper
和mybatis自定义分页
,那么在运行的时候没有生效,那么如果你在找过其他的一些配置问题都没有问题之后。
这里的问题就是开头我们提到的问题,这里的问题的核心原因其实是因为spring没有加载进来mybatisPlusInterceptor
,那么我们就需要使用下面这种方式加入到spring中
@Autowired
private List<SqlSessionFactory> sqlSessionFactoryList;
/**
* 分页插件, 对于单一数据库类型来说,都建议配置该值,避免每次分页都去抓取数据库类型
*/
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new ExamPaginationInnerInterceptor());
return interceptor;
}
/**
* 只会执行一次
* 顺序:Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)
*/
@PostConstruct
public void addMysqlInterceptor() {
//创建自定义mybatis拦截器,添加到chain的最后面
for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
org.apache.ibatis.session.Configuration configuration = sqlSessionFactory.getConfiguration();
//自己添加
configuration.addInterceptor(mybatisPlusInterceptor());
}
}
案例描述三:自动创建时间修改时间等无法加入
我们在新加数据的时候总会去加入创建时间和修改时间,但是上面配置都没有生效,如果你在确认了其他的一些配置都没有问题了
这里该配置的都配置好了,那么在检查一下这个方法
MybatisSqlSessionFactoryBean
有没有把你的配置给加进来
@Slf4j
@Component
public class DateConfig implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.debug("mybatis plus start insert fill ....");
LocalDateTime now = LocalDateTime.now();
// 审计字段自动填充,覆盖用户输入
fillValIfNullByName("createTime", now, metaObject, true);
fillValIfNullByName("updateTime", now, metaObject, true);
fillValIfNullByName("createBy", getUserName(), metaObject, true);
fillValIfNullByName("updateBy", getUserName(), metaObject, true);
}
// .............
然后在SqlSessionFactory
将这个方法计入进来
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception{
MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
GlobalConfig globalConfig = GlobalConfigUtils.defaults();
//mybatis-plus全局配置设置元数据对象处理器为自己实现的那个
globalConfig.setMetaObjectHandler(new DateConfig());
sessionFactory.setGlobalConfig(globalConfig);
return sessionFactory.getObject();
}
总结
这里的问题都是引入不同的依赖分页导致的,以上就是本人踩过的坑总结,如果有帮到你请留心你的赞。