今天准备了一个使用Spring Boot的例子,在Spring-MyBatis旁边使用MyBatis进行数据访问通信。这是相关的项目配置(使用maven):
src/main/java
- edu.home.ltmj.controller
+ CategoryController.java
- edu.home.ltmj.dao
+ CategoryDao.java
- edu.home.ltmj.domain
+ Category.java
src/main/resources
- edu.home.ltmj.dao
+ CategoryMapper.xml
文件的相关内容:
CategoryDao.java:
package edu.home.ltmj.dao;
public interface CategoryDao {
List<Category> getAllCategories();
}
类别映射器.xml:
<mapper namespace="edu.home.ltmj.dao.CategoryDao">
<resultMap id="categoryMap"
type="edu.home.ltmj.domain.Category">
<id property="id" column="id" />
<result property="name" column="name" />
</resultMap>
<select id="getAllCategories" resultMap="categoryMap">
SELECT id, nombre
FROM category
</select>
</mapper>
然后,我在请求控制器中注入这个 dao 的一个实例(用于测试目的),如下所示:
package edu.home.ltmj.controller;
@RestController
public class CategoryController {
@Autowired
private CategoryDao dao;
@RequestMapping(value="/category/all",
method=RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_VALUE)
public List<Categoria> getAllCategories() {
return dao.getAllCategories();
}
}
我运行我的项目并通过使用测试执行curl localhost:8080/category/all
,然后期望看到 JSON 格式的结果,但我得到了这个异常:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): edu.home.ltmj.dao.CategoryDao.getAllCategories
at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:189)
at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:43)
at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:58)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:51)
at com.sun.proxy.$Proxy45.getAllCategories(Unknown Source)
at edu.home.ltmj.controller.CategoryRestController.getAllCategories(CategoryRestController.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
(...)
我不明白这是什么原因。有一个接口CategoryDao
,它有与 .getAllCategories
匹配的正确方法<select id="getAllCategories">
。在玩了一段时间后,我将 dao 接口的名称更改为CategoryMapper
并更新了 CategoryMapper.xml 中的命名空间。在我这样做之后,一切正常。此外,在类和 xml 具有相同名称后,我将 dao 类和 xml 映射器移动到不同的包中(仍然使用相同的名称:CategoryMapper。),更新 xml 文件中的命名空间,并得到相同的异常, 更新消息以显示 dao 接口的包名。但是话又说回来,我将两个文件都移到了同一个包中,一切都恢复了。
所以,我的问题是:为什么 MyBatis 需要接口和 xml 映射器文件具有相同的名称并在同一个包中?这是 MyBatis 的设计还是 Spring MyBatis 的问题?