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 属性上定义。