gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:09:07 24 4
gpt4 key购买 nike

今天准备了一个使用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 的一个实例注入(inject)请求 Controller (用于测试目的),如下所示:

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)
(...)

我不明白这是什么原因。有一个接口(interface) CategoryDao它有正确的方法 getAllCategories<select id="getAllCategories"> 匹配.玩了一段时间后,我将 dao 接口(interface)的名称更改为 CategoryMapper并更新了 CategoryMapper.xml 中的命名空间。在我这样做之后,一切正常。此外,在类和 xml 具有相同名称后,我将 dao 类和 xml 映射器移动到不同的包中(仍然使用相同的名称:CategoryMapper。),更新 xml 文件中的 namespace ,并得到相同的异常, 消息已更新以显示 dao 接口(interface)包的名称。但话又说回来,我将这两个文件移动到同一个包中,一切又恢复正常了。

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

最佳答案

你还有MyBatis Config文件吗?

如果我没记错的话,XML 文件的名称与接口(interface)的位置相同,当您想要一个无需额外配置即可正常工作的设置时。

如果您在其他地方有 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.

那么试试这个:

  1. 创建 mybatis-config.xml里面的文件src/main/resources里面有这个:

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

关于java - 为什么接口(interface)和xml映射器文件必须在同一个包中并具有相同的名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30253696/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com