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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30081542/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 09:05:16  来源:igfitidea点击:

MyBatis Spring MVC Error: Invalid bound statement (not found)

javaspringspring-mvcmybatis

提问by Jail

Here is the stack trace when I try to execute a simple query using MyBatis:

这是我尝试使用 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$40c60a.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)

I'm using Javaconfig syntax instead of XML configuration. Here is my PersistenceConfig:

我使用的是 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;
    }
}

Here is my controller:

这是我的控制器:

@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";
    }

}

Here is my Brand Mapper Interface:

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

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);

}

Here is my BrandMapper XML:

这是我的 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>

I've done some research, but none of the solutions have worked for me. My XML Mapper files are under resources in a package named "com.my.package.persistence"

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

Does anyone have an idea what's wrong here?

有谁知道这里有什么问题?

Thanks in advance

提前致谢

回答by S_intg

I guess Maybe you need a @Aliasannotation:

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

@Alias("Brand") class Brand{ ... }

@Alias("Brand") class Brand{ ... }

this is the first thing comes to my mind hope it helps !

这是我想到的第一件事希望它有帮助!

回答by Karthik Prasad

If you had run the JUNIT of the db service code, it would have worked. Hence I believe its the probmlem when WAR file is generated, from your configuration *Mapper.java and *Mapper.xml points to same location, Hence when war is gerenated folder path for both java and xml files would be WEB-INF/classes/com/my/package/persistence. However *.xml file is not copied to the location. One way is to configure you build script to copy the xml files as well or otherway(which I would prefer) to create sqlmap directory in resources directory and copy all the xml mapper files to the directory and point to mapperfile location using sessionFactory.setMapperLocationsand once war file is generated make sure sqlmap directory is present in WEB-INF/classesdirectory

如果您运行了 db 服务代码的 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目录中

回答by Akash Rajbanshi

Remove the ;from the query:

;从查询中删除:

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

回答by Aldo Ernesto Arias Figueroa

Try checking the mybatis-conf.xml (whatever name your called this file) file and see if you have your xml mapper like this:

尝试检查 mybatis-conf.xml(不管你叫这个文件的名字)文件,看看你是否有这样的 xml 映射器:



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

回答by Lucky

Error message:

错误信息

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

Most probably due to a wrong mapper Query Syntax. I had this problem many times and every time the error is caused by a wrong syntax of the query written in the Mapper xml and interface files. I suggest you to,

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

  • Re-check your query properly which is mainly the reason for this error.
  • Configuration => Might also be caused due to invalid configuration of mapper files(interface & xml) in configuration files.
  • Do maven clean, maven install(rebuild) and then restart the server
  • 正确地重新检查您的查询,这主要是导致此错误的原因。
  • 配置 => 也可能是由于配置文件中映射器文件(接口和 xml)的配置无效造成的。
  • 做 maven clean, maven install(rebuild) 然后重启服务器

回答by HymanJonesAngel

You should provide mapper locations when initialize sqlSessionFactory:

您应该在初始化 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;
   }

In your case, replace "classpath:path/to/mappers/*.xml"with classpath:com/my/package/persistence/*.xml

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

Hope this will help you.

希望这会帮助你。

回答by derek

I had this exact error message, turned out to be the namespace path in the mapper xml file, I had changed the package name in the java interface file but forgot to update the package name in the maper xml, bit of an odd one. Updated the package namespace and hey presto!

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

回答by Sravan

Your mapper file should be in the same package as the *Repo.java file is. Please check the mapper namespace too.

您的映射器文件应该与 *Repo.java 文件在同一个包中。请检查映射器命名空间。