将ruoyi-vue框架改造集成mybatis-plus中遇到的坑总结。
什么是ruoyi-vue
RuoYi-Vue 是一个 Java EE 企业级快速开发平台,基于经典技术组合(Spring Boot、Spring Security、MyBatis、Jwt、Vue),内置模块如:部门管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、代码生成等。在线定时任务配置;支持集群,支持多数据源,支持分布式事务。
以上来自官网介绍,总之是一个脚手架功能的开源框架。具体内容详见官网:https://doc.ruoyi.vip/ruoyi-vue/
集成mybatis-plus遇到的问题
由于ruoyi-vue脚手架实际上也是使用了SpringBoot,那么我们集成mybatis-plus是很方便的,只需要在pom文件上加以下依赖即可:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
但是实际情况就是,虽然我们在代码编写过程中可以使用mybatis-plus的api,而且程序也能启动成功(尽管没有打印出标志性的mybatis-plus启动印),但是一旦进行接口调用就会出现Invalid bound statement (not found):xxxMapper.insert的错误,仿佛mybatis-plus压根就没生效。
解决思路
怀疑是不是ruoyi框架本身做了什么特殊处理导致mybatis-plus没有生效。由于考虑到ruoyi本身使用的是mybatis,于是查找到相关的MyBatisConfig配置类,如下:
/**
* Mybatis支持*匹配扫描包
*
* @author ruoyi
*/
@Configuration
public class MyBatisConfig
{
@Autowired
private Environment env;
static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
public static String setTypeAliasesPackage(String typeAliasesPackage)
{
ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
// ...省略
}
public Resource[] resolveMapperLocations(String[] mapperLocations)
{
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
// ...省略
}
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
{
String typeAliasesPackage = env.getProperty("mybatis.type-aliases-package");
String mapperLocations = env.getProperty("mybatis.mapper-locations");
// ...省略
}
}
我们重点关注最后一段SqlSessionFactory,这里是在项目启动之初配置SqlSessionFactory。尝试注释掉这一段代码,再次启动,发现熟悉的mybatis-plus启动标出现了,经过接口测试发现功能也一切正常了。
那么实际上这个SqlSessionFactory的bean确实影响到了mybatis-plus,通过源码得知当项目已经有配置SqlSessionFactory,mybatis-plus将不会自动帮我们注入SqlSessionFactory,而使用我们自己定义的SqlSessionFactory。
实际上mybatis-plus需要的是MybatisSqlSessionFactoryBean,而不是SqlSessionFactoryBean。
以上我们通过注释掉该代码,使得mybatis-plus自动帮我们注入SqlSessionFactoryBean。或者我们也可以调整该代码,使得手动将其中的SqlSessionFactoryBean修改为MybatisSqlSessionFactoryBean。
在application.yml的配置文件部分我们也可以加上关于mybatis-plus的配置信息:
# mybatisplus
mybatis-plus:
type-aliases-package: com.vainycos.**.domain,com.vainycos.**.entity
mapper-locations: classpath*:mapper/**/*Mapper.xml
config-location: classpath:mybatis/mybatis-config.xml
额外
以上我们解决了集成mybatis-plus的问题,但是随之而来的又遇上了使用mybatis-plus的page分页方法不返回total总数的问题…真是一波还未平息,一波又来侵袭。
于是继续深挖该问题,发现项目中自带了pagehelper的相关依赖:
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.boot.version}</version>
</dependency>
有没有可能是pagehelper分页插件与mybatis-plus之间发生了冲突。
此时有两种解决方式,一种是将pagehelper的相关依赖全部移除。该方式在后续的实践过程中直接被毙了,因为依赖使用到的地方太多了。
于是就尝试用第二种方式,手动写一个MybatisPlusConfig注入MybatisPlusInterceptor来解决分页问题:
@Configuration
public class MyBatisPlusConfig {
/**
* 分页插件 ps: 如果引入了pageHelper 就需要手动注入mybatisPlus的分页拦截器
*/
@Bean
public MybatisPlusInterceptor innerInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//这里是重点
return interceptor;
}
}
最终校验结果发现成功解决了分页不返回total总数的问题。
参考资料: