繁体   English   中英

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

[英]Why must the interface and xml mapper file be in same package and have the same name?

今天我正在准备一个使用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映射器,则可以使用MyBatis配置中<mappers>元素手动指定XML文件的类路径。

Injecting Mappers文档中:

如果UserMapper在与mapper接口相同的类路径位置中具有相应的MyBatis XML映射器文件,则它将由MapperFactoryBean自动解析。 除非映射器XML文件位于不同的类路径位置,否则无需在MyBatis配置文件中指定映射器。 有关更多信息,请参阅SqlSessionFactoryBean的configLocation属性。

试试这个:

  1. 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包含的内容。

  2. 设置配置文件的位置(Java配置如下或applicationContext文件中的bean):

     @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

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

2)设置类别道

@Bean
public CategoryDao getCategoryDao() throws Exception{
    SqlSessionTemplate sessionTemplate = new SqlSessionTemplate(sqlSessionFactoryBean());
    return sessionTemplate.getMapper( CategoryDao.class );
}

3)在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>

    <settings>
        <setting name="logImpl" value="COMMONS_LOGGING"/>
    </settings>

    <mappers>

        <mapper class="CategoryMapper.xml"/>
    </mappers>

</configuration>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM