MyBatis Spring MVC 错误:无效的绑定语句(未找到)

问题描述 投票:0回答:11

这是我尝试使用 MyBatis 执行简单查询时的堆栈跟踪:

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.my.package.persistence.BrandMapper.getBrand
    org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:189)
    org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:43)
    org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:58)
    org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:51)
    com.sun.proxy.$Proxy25.getBrand(Unknown Source)
    com.my.package.service.BrandService.getBrand(BrandService.java:18)
    com.my.package.service.BrandService$$FastClassBySpringCGLIB$$1140c60a.invoke(<generated>)
    org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:649)
    com.my.package.service.BrandService$$EnhancerBySpringCGLIB$$ea6f89cd.getBrand(<generated>)
    com.my.package.controller.HomeController.getBrands(HomeController.java:28)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:483)
    org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

我使用 Javaconfig 语法而不是 XML 配置。这是我的 PersistenceConfig:

@Configuration
@EnableTransactionManagement
@MapperScan("com.my.package.persistence")
public class PersistenceConfig {

    @Bean
    public DataSource dataSource() {

        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        try {
            dataSource.setDriverClassName("com.mysql.jdbc.Driver");
            dataSource.setUrl("jdbc:mysql//localhost:3306/db");
            dataSource.setUsername("dbuser");
            dataSource.setPassword("dbpassword");
        } catch (Exception e) {
            System.out.print(e);
        }
        return dataSource;
    }

    @Bean
    public DataSourceTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setTypeAliasesPackage("com.my.package.domain");
        return sessionFactory;
    }
}

这是我的控制器:

@Controller
public class HomeController {

    private static Logger logger = LoggerFactory.getLogger(HomeController.class);

    @Autowired
    private BrandService brandService;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index() {
        return "index";
    }

    @RequestMapping(value = "/brands", method = RequestMethod.GET)
    public String getBrands(Model model) {
        model.addAttribute("brands",brandService.getBrand(1));
        return "brands";
    }

}

这是我的品牌映射器界面:

public interface BrandMapper {

    Brand getBrand(int id);

    Brand getBrandByName(String name);

    List<Brand> getBrandList();

    void addBrand(Brand brand);

    void updateBrand(Brand brand);

    void deleteBrand(int id);

}

这是我的 BrandMapper XML:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.my.package.persistence.BrandMapper">

    <select id="getBrand" resultType="Brand" parameterType="int">
        SELECT id, name
        FROM brand
        WHERE id = #{id};
    </select>

    <select id="getBrandByName" resultType="Brand" parameterType="String">
        SELECT id, name
        FROM brand
        WHERE name = #{name};
    </select>

    <select id="getBrandList" resultType="Brand">
        SELECT id, name
        FROM brand;
    </select>

    <insert id="addBrand" parameterType="Brand">
        INSERT INTO brand (id, name)
        VALUE (#{id}, #{name})
    </insert>

    <update id="updateBrand" parameterType="Brand">
        UPDATE brand
        SET
        name = #{name}
        where id = #{id}
    </update>

    <delete id="deleteBrand" parameterType="int">
        DELETE FROM brand
        WHERE id = #{id}
    </delete>

</mapper>

我做了一些研究,但没有一个解决方案对我有用。我的 XML Mapper 文件位于名为“com.my.package.persistence”的包中的资源下

有人知道这里出了什么问题吗?

提前致谢

java spring spring-mvc mybatis
11个回答
9
投票

尝试检查 mybatis-conf.xml(无论您将此文件命名为什么名称)文件,看看您是否有这样的 xml 映射器:


<mappers> 
    <mapper resource="BrandMapper.xml">
<mappers>

5
投票

错误信息

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):

很可能是由于错误的映射器查询语法。我多次遇到这个问题,每次错误都是由 Mapper xml 和接口文件中编写的查询语法错误引起的。我建议你,

  • 重新正确检查您的查询,这主要是导致此错误的原因。
  • Configuration => 也可能是由于配置文件中的mapper文件(接口和xml)配置无效导致的。
  • 执行maven clean,maven install(rebuild),然后重新启动服务器

3
投票

您应该在初始化 sqlSessionFactory 时提供映射器位置:

    @Autowired
    private ResourceLoader resourceLoader;

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        //sessionFactory.setTypeAliasesPackage("com.my.package.domain");
        sessionFactory.setMapperLocations(ResourcePatternUtils.getResourcePatternResolver(resourceLoader).
            getResources("classpath:path/to/mappers/*.xml"));
        return sessionFactory;
   }

在您的情况下,将 "classpath:path/to/mappers/*.xml" 替换为 classpath:com/my/package/persistence/*.xml

希望这对您有帮助。


1
投票

如果您运行了数据库服务代码的 JUNIT,它就会起作用。因此,我相信它是生成 WAR 文件时的问题,从您的配置 *Mapper.java 和 *Mapper.xml 指向同一位置,因此,当生成 war 时,java 和 xml 文件的文件夹路径将是

WEB-INF/classes/com/my/package/persistence
。但是 *.xml 文件不会复制到该位置。一种方法是配置构建脚本以复制 xml 文件,或者以其他方式(我更喜欢)在资源目录中创建 sqlmap 目录,并将所有 xml 映射器文件复制到该目录,并使用
sessionFactory.setMapperLocations
和指向映射器文件位置一旦生成了 war 文件,请确保 sqlmap 目录存在于
WEB-INF/classes
目录


1
投票

我收到了这个确切的错误消息,原来是mapper xml文件中的名称空间路径,我更改了java接口文件中的包名称,但忘记更新maper xml中的包名称,有点奇怪。更新了包命名空间,嘿,快点!


1
投票

在资源中,创建目录是

"com/stackflow/mapper"
,不是
"com.stackflow.mapper"
。因为前者是文件名,后者是目录


0
投票

我想也许你需要一个 @Alias 注释:

@Alias(“品牌”) 类品牌{ ... }

这是我首先想到的希望它有帮助!


0
投票

从查询中删除

;

<select id="getBrand" resultType="Brand" parameterType="int">
    SELECT id, name
    FROM brand
    WHERE id = #{id}
</select>

0
投票

您的映射器文件应与 *Repo.java 文件位于同一包中。请也检查映射器名称空间。


0
投票

刚刚用

gradle clean build
修复了。


0
投票

就我而言,我将

mapper.xml
文件放置在与
mapper.java
相同的目录中,但这些 XML 资源并未复制到类路径中。我通过在我的
pom.xml
中包含以下配置来解决此问题,以确保正确的资源复制:

<build>
    <!-- mybatis mapper -->
    <resources>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>

希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.