[Mybatis]xxx is ambiguous in Mapped Statements collection

116 阅读1分钟

Mybatis 常见异常:org.apache.ibatis.exceptions.PersistenceException:

### Error querying database.  Cause: java.lang.IllegalArgumentException: selectAll is ambiguous in Mapped Statements collection (try using the full name including the namespace, or rename one of the entries)
### Cause: java.lang.IllegalArgumentException: selectAll is ambiguous in Mapped Statements collection (try using the full name including the namespace, or rename one of the entries)

在使用 SqlSession 调用查询方法时,报出的这个错误。代码如下:

public class TestEmp {

    private SqlSession session;

    @Before
    public void before() throws IOException {
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        InputStream is = Resources.getResourceAsStream("sqlMapperConfig.xml");
        SqlSessionFactory factory = builder.build(is);
        session = factory.openSession();
    }

    @After
    public void after() {
        session.close();
    }

    @Test
    public void testSelectAll() {
        List<Emp> list = session.selectList("selectAll");
        list.forEach(System.out::println);
    }
}

这是 EmpMapper 映射文件内部代码:

<select id="selectAll" resultType="org.codeArt.pojo.Emp">
    select * from `emp`
</select>

最后经过排查得出是 XML 文件件中的 CRUD 方法的 id 重复,需要加上命名空间才行,不然 Mybatis 不能识别这个方法对应的是哪个 Mapper 文件内的查询标签。我在另一个 Mapper 文件 DeptMapper 文件中定义了如下查询标签:

<select id="selectAll" resultType="org.codeArt.pojo.Dept">
    select * from `dept`
</select>

这个标签的 id 属性的值和上面那个是一样的,所以调用时会产生冲突。解决方法就是调用时加上命名空间:

@Test
public void testSelectAll() {
    List<Emp> list = session.selectList("org.codeArt.mapper.EmpMapper.selectAll");
    list.forEach(System.out::println);
}

这样就能正常运行。注意:org.codeArt.mapper.EmpMapper.selectAll 是你自己定义的 Mapper 文件中的命名空间加上对应的查询标签的 id 值,上面的 DeptMapper 假如想调用内部的方法那就加上 org.codeArt.mapper.DeptMapper.selectAll。命名空间可以在 mapper 标签的 namespace 属性上定义。