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
MyBatis Spring MVC Error: Invalid bound statement (not found)
提问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.setMapperLocations
and once war file is generated make sure sqlmap directory is present in WEB-INF/classes
directory
如果您运行了 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 文件在同一个包中。请检查映射器命名空间。