1. 复现问题
今天升级了mybatis-plus
框架,但在测试如下代码时:
@SpringBootTest
class LowCodeApplicationTests {
@Autowired private EnterpriseUserService enterpriseUserService;
@Test
void contextLoads() {}
@Test
public void testLogin() {
// 查询企业
QueryWrapper<EnterpriseUser> qw = new QueryWrapper<>();
qw.eq("user_id",1);
EnterpriseUser enterpriseUser = enterpriseUserService.getOne(qw);
System.out.println(enterpriseUser);
}
}
却报出如下下错误:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.cloud.lowcode.mapper.EnterpriseUserMapper.selectList
at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235)
at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:53)
at org.apache.ibatis.binding.MapperProxy.lambda$cachedInvoker$0(MapperProxy.java:108)
at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1688)
at org.apache.ibatis.util.MapUtil.computeIfAbsent(MapUtil.java:35)
at org.apache.ibatis.binding.MapperProxy.cachedInvoker(MapperProxy.java:95)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86)
at com.sun.proxy.$Proxy115.selectList(Unknown Source)
at com.baomidou.mybatisplus.core.mapper.BaseMapper.selectOne(BaseMapper.java:173)
at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)
at org.apache.ibatis.binding.MapperProxy$DefaultMethodInvoker.invoke(MapperProxy.java:159)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86)
at com.sun.proxy.$Proxy115.selectOne(Unknown Source)
at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.getOne(ServiceImpl.java:202)
at com.baomidou.mybatisplus.extension.service.IService.getOne(IService.java:320)
at com.baomidou.mybatisplus.extension.service.IService$$FastClassBySpringCGLIB$$f8525d18.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at com.cloud.lowcode.service.EnterpriseUserService$$EnhancerBySpringCGLIB$$2a58f5f.getOne(<generated>)
at com.cloud.lowcode.LowCodeApplicationTests.testLogin(LowCodeApplicationTests.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at
......
即org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.cloud.lowcode.mapper.EnterpriseUserMapper.selectList
2. 分析问题
我在EnterpriseUserMapper.java
文件中并没有写selectList
方法,而是继承了BaseMapper
类,如下代码所示:
package com.cloud.lowcode.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cloud.lowcode.entity.po.EnterpriseUser;
/**
* @author zby
* @datetime 2022/11/29 15:48
* @desc 企业用户
*/
public interface EnterpriseUserMapper extends BaseMapper<EnterpriseUser> {}
因而,BaseMapper
中存在selectList
方法,而BaseMapper
存在于mybatis plus
中的,这就是说明mybatis
包冲突,导致依赖包使用的不是mybatis plus
的包。
引入MyBatis-Plus
之后请不要再次引入MyBatis
以及MyBatis-Spring
,以避免因版本差异导致的问题。
3. 解决问题
- 检查是否引入了
Mybatis plus
依赖
<properties>
<baomidouMybatisPlus.version>3.5.2</baomidouMybatisPlus.version>
</properties>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>${baomidouMybatisPlus.version}</version>
</dependency>
- 删除导致冲突的
mybatis
其它依赖
检查pom.xml
文件中是否引入了其它mybatis
的依赖项,如果有以下依赖,可以直接注释或删除:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatisplus-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.4</version>
</dependency>
spring boot
中的sqlSessionFactory bean
配置
sqlSessionFactory
不是mybatis plus
的SqlSessionFactory
,因而,我们需要如下配置类(MybatisPlusConfig.java)
:
/**
* @author 念兮为美
* @datetime 2022/11/28 14:10
* @desc mybatis plus 配置类
*/
@Configuration
public class MybatisPlusConfig {
private String mapperLocations = "classpath*:/mapper/*Mapper.xml";
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource)
throws Exception {
final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));
return sessionFactory.getObject();
}
}
如是这样配置之后,项目能构成运行:
假设,我们不写MybatisPlusConfig.java
这个配置,它会报出如下错误:
Caused by: java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
at org.springframework.util.Assert.notNull(Assert.java:201)
at org.mybatis.spring.support.SqlSessionDaoSupport.checkDaoConfig(SqlSessionDaoSupport.java:122)
at org.mybatis.spring.mapper.MapperFactoryBean.checkDaoConfig(MapperFactoryBean.java:73)
at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1845)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782)
... 96 more