Why must the interface and xml mapper file be in same package and have the same name?
今天,我正在准备一个使用Spring Boot并使用MyBatis进行Spring-MyBatis旁边的数据访问通信的示例。以下是相关的项目配置(使用Maven):
1 2 3 4 5 6 7 8 9 10 | 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:
1 2 3 4 5 | package edu.home.ltmj.dao; public interface CategoryDao { List<Category> getAllCategories(); } |
CategoryMapper.xml:
1 2 3 4 5 6 7 8 9 10 11 | <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的一个实例(出于测试目的),如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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(); } } |
我运行我的项目并使用
1 2 3 4 5 6 7 8 9 | 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) (...) |
我不明白原因。有一个接口
所以,我的问题是:为什么MyBatis需要接口和xml映射器文件具有相同的名称并位于相同的包中?这是MyBatis设计还是Spring MyBatis中的问题?
您还有MyBatis Config文件吗?
如果我没有记错的话,当您想要进行无需额外配置的设置时,XML文件的名称与接口的位置相同。
如果您在其他地方有XML映射器,则可以使用MyBatis配置内的
来自"注入映射器"文档:
If the UserMapper has a corresponding MyBatis XML mapper file in the same classpath location as the mapper interface, it will be parsed automatically by the MapperFactoryBean. There is no need to specify the mapper in a MyBatis configuration file unless the mapper XML files are in a different classpath location. See the SqlSessionFactoryBean's configLocation property for more information.
因此,请尝试以下操作:
在
1 2 3 4 5 6 7 8 9 | <?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> <mappers> <mapper resource="com/test/path/etc/etc/WhateverNameYouWant.xml"/> </mappers> </configuration> |
设置配置文件的位置(如下所示的Java配置或
1 2 3 4 5 6 7 8 | @Bean public SqlSessionFactoryBean sqlSessionFactory() throws Exception { SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); // .... sessionFactory.setConfigLocation(new ClassPathResource("mybatis-config.xml")); // .... return sessionFactory; } |
我在没有@MapperScan的情况下使用了以下方式:
1)就像上面的步骤2一样设置mybatis-config.xml
1 2 3 4 5 6 7 8 | @Bean public SqlSessionFactoryBean sqlSessionFactory() throws Exception { SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); // .... sessionFactory.setConfigLocation(new ClassPathResource("mybatis-config.xml")); // .... return sessionFactory; } |
2)设置CategoryDao
1 2 3 4 5 | @Bean public CategoryDao getCategoryDao() throws Exception{ SqlSessionTemplate sessionTemplate = new SqlSessionTemplate(sqlSessionFactoryBean()); return sessionTemplate.getMapper( CategoryDao.class ); } |
3)在mybatis-config.xml
中进行设置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?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="logImpl" value="COMMONS_LOGGING"/> </settings> <mappers> <mapper class="CategoryMapper.xml"/> </mappers> </configuration> |