MyBatis 无法识别映射器 xml 文件 - 无效的绑定语句(未找到)
Posted
技术标签:
【中文标题】MyBatis 无法识别映射器 xml 文件 - 无效的绑定语句(未找到)【英文标题】:MyBatis not recognizing mapper xml file - Invalid bound statement (not found) 【发布时间】:2021-04-23 22:06:38 【问题描述】:我在尝试从数据库中提取数据时遇到此类错误。
不知何故,MyBatis 无法识别我的映射器 xml 文件,接口映射器和 xml 映射器具有相同的文件名和相同的目录。
但是,当我使用此注释时,它可以工作@Select("SELECT id, client_number, name, email, health_condition FROM client.data WHERE id = #id")
我不想使用 @Select 注释,而是想使用我的映射器 xml 文件。
有没有人有任何想法来解决这个问题?
我正在使用 Gradle(最新)、Java15 和 SpringBoot2.4.1
出现意外错误(类型=内部服务器错误, 状态=500)。无效的绑定语句(未找到): nutri.api.infrastructure.datasource.client.ClientMapper.getClientById org.apache.ibatis.binding.BindingException:绑定语句无效 (未找到): nutri.api.infrastructure.datasource.client.ClientMapper.getClientById 在 org.apache.ibatis.binding.MapperMethod$SqlCommand.(MapperMethod.java:235) 在 org.apache.ibatis.binding.MapperMethod.(MapperMethod.java:53) 在 org.apache.ibatis.binding.MapperProxy.lambda$cachedInvoker$0(MapperProxy.java:115) 在 java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708) 在 org.apache.ibatis.binding.MapperProxy.cachedInvoker(MapperProxy.java:102) 在 org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:85) 在 com.sun.proxy.$Proxy58.getClientById(未知来源) nutri.api.infrastructure.datasource.client.ClientDatasource.getClientById(ClientDatasource.java:18) 在 nutri.api.infrastructure.datasource.client.ClientDatasource$$FastClassBySpringCGLIB$$fcc24d17.invoke() 在 org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) 在 org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) 在 org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) 在 org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) 在 org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) 在 org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691) 在 nutri.api.infrastructure.datasource.client.ClientDatasource$$EnhancerBySpringCGLIB$$42a63ac2.getClientById() 在 nutri.api.application.service.ClientService.getClientById(ClientService.java:15) 在 nutri.api.presentation.controller.ClientApiController.get(ClientApiController.java:20) 在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 方法)在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) 在 java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.base/java.lang.reflect.Method.invoke(Method.java:564) 在 org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) 在 org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141) 在 org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) 在 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) 在 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) 在 org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) 在 org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1061) 在 org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:961) 在 org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) 在 org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:626) 在 org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:733) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在 org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在 org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在 org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在 org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) 在 org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) 在 org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) 在 org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888) 在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597) 在 org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) 在 java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) 在 java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) 在 org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 在 java.base/java.lang.Thread.run(Thread.java:832)
【问题讨论】:
您提供的那一点信息很难提供帮助。请包含映射器xml文件和映射器接口。 @Leo 此错误最常见的错误是 XML 位于src/main/java
而不是 src/main/resources
。由于此错误还有许多其他可能的原因,因此获得答案的最快方法是在 GitHub 上分享您的项目。 :)
@ave 这是我的项目github.com/nnakamura95/nutri/tree/develop
@Leo 仓库中似乎没有 XML 文件。 ???它应该位于此路径中:nutri/nutri-api/src/main/resources/nutri/api/infrastructure/datasource/client/ClientMapper.xml
.
当前路径为nutri/nutri-api/src/main/resources/ClientMapper.xml
。正确的路径是nutri/nutri-api/src/main/resources/nutri/api/infrastructure/datasource/client/ClientMapper.xml
。请仔细比较。 ???顺便说一句,似乎还有其他几个问题(属性名称不匹配,缺少 UUID 的类型处理程序)。
【参考方案1】:
我遇到了类似的问题,一位高级开发人员帮我弄清楚,Clientmapper.xml 文件应该与 ClientMapper java 接口位于类似的包中。
有时,当我们在src/main/resources
中创建一个目录为nutri.api.infrastructure.datasource.client
时,它会创建一个文件夹名称为"nutri.api.infrastructure.datasource.client"
的文件夹。
一种解决方法是使用系统资源管理器手动创建此文件夹结构,并且可以肯定的是,您还可以检查项目Structure>Modules
并确认它具有分层文件夹结构。
【讨论】:
【参考方案2】:要在 xml 文件中使用映射器的声明,您应该在包含映射器声明的类路径 (/src/main/resources) 中声明配置文件,例如 mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- <setting name="aggressiveLazyLoading" value="false"/>-->
<!-- <setting name="lazyLoadingEnabled" value="false"/>-->
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/>-->
<!-- <setting name="logImpl" value="SLF4J"/>-->
<!-- <setting name="jdbcTypeForNull" value="NULL"/>-->
<!-- <setting name="callSettersOnNulls" value="true"/>-->
</settings>
<typeAliases>
<!-- Data Transfer Objects -->
</typeAliases>
<typeHandlers>
<!-- <typeHandler handler="org.apache.ibatis.type.LocalDateTimeTypeHandler"/>-->
</typeHandlers>
<!-- explicit inclusion of reusable elements -->
<mappers>
<mapper resource="yourMapper.xml" />
</mappers>
</configuration>
此外,您应该在 SqlSessionFactory bean 中设置配置文件的路径,例如:
@Bean
public SqlSessionFactory sqlSessionFactory(final DataSource dataSource) throws Exception
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setConfigLocation(new PathMatchingResourcePatternResolver().getResource("classpath:mybatis-config.xml"));
bean.setDataSource(dataSource);
return bean.getObject();
【讨论】:
以上是关于MyBatis 无法识别映射器 xml 文件 - 无效的绑定语句(未找到)的主要内容,如果未能解决你的问题,请参考以下文章