java – 为什么接口和xml映射器文件必须在同一个包中并且具有相同的名称?

今天我正在准备一个使用Spring Boot并使用MyBatis进行Spring-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();
}

CategoryMapper.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中的命名空间.在我这样做之后,一切正常.此外,在为class和xml命名之后,我将dao类和xml映射器移动到不同的包中(stil使用相同的名称同时为:CategoryMapper.),更新了xml文件中的命名空间,并获得了相同的异常,更新消息以显示dao接口的包的名称.但话说回来,我把两个文件都移到同一个包中,一切都恢复了.

所以,我的问题是:为什么MyBatis需要接口和xml映射器文件具有相同的名称并且在同一个包中?这是MyBatis设计还是Spring MyBatis中的一个问题?

最佳答案
你还有一个MyBatis配置文件吗?

如果我没有正确记住XML文件的相同名称与接口相同,那么当您希望设置无需额外配置时即可使用.

如果您在其他地方有XML映射器,则可以使用< mappers>手动指定XML文件的类路径.元素里面MyBatis configuration.

Injecting Mappers documentation:开始

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.

试试这个:

>在src / main / resources中创建一个mybatis-config.xml文件,其中包含:

<?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>

WhateverNameYouWant.xml包含CategoryMapper.xml包含的内容.
>设置配置文件的位置(如下所示的Java配置或applicationContext文件中的bean):

@Bean
public SqlSessionFactoryBean sqlSessionFactory() throws Exception {
    SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    // ....
    sessionFactory.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
    // ....
    return sessionFactory;
}

转载注明原文:java – 为什么接口和xml映射器文件必须在同一个包中并且具有相同的名称? - 代码日志