解决异常:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

1.bug背景

1.1.MyBatis配置文件

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

    <!-- 引入外部配置文件 -->
    <properties resource="jdbc.properties"/>

    <!-- environments:多环境配置的标签 元配置信息default必须存在, 代表使用作为默认加载的环境 -->
    <environments default="development">
        <!--  environment标签代表具体的某个环境配置信息id必须存在,作为当前环境的唯一标志-->
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!--dataSource表示数据源的配置:=>POOLED代表使用连接池 =>UNPOOLED:代表直连-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <package name="pers.lintao.dao"/>
    </mappers>

</configuration>

 1.2.映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="pers.lintao.dao.PersonTableDao">

    <resultMap type="pers.lintao.entity.PersonTable" id="PersonTableMap">
        <result property="id" column="id" jdbcType="INTEGER"/>
        <result property="pname" column="pname" jdbcType="VARCHAR"/>
        <result property="psex" column="psex" jdbcType="VARCHAR"/>
        <result property="idCardId" column="id_card_id" jdbcType="INTEGER"/>
    </resultMap>

    <!--查询单个-->
    <select id="queryById" resultMap="PersonTableMap">
        select
          id, pname, psex, id_card_id
        from person_table
        where id = #{id}
    </select>

</mapper>

 1.3.dao层接口

public interface PersonTableDao {

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    PersonTable queryById(Integer id);

}

 1.4.工具类

public class MyBatisUtil {

    private static SqlSession sqlSession;

    public static SqlSession createSqlSession() throws IOException {
        Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        sqlSession = sqlSessionFactory.openSession();
        return sqlSession;
    }

    public static void close(SqlSession sqlSession){
        sqlSession.close();
    }
}

 1.5.单元测试

@Test
    public void testQuery() throws Exception {
        SqlSession sqlSession = null;
        try {
            sqlSession = MyBatisUtil.createSqlSession();
            PersonTableDao mapper = sqlSession.getMapper(PersonTableDao.class);
            PersonTable personTable = mapper.queryById(1);
            System.out.println(personTable);
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("创建SqlSession出错异常");
        } finally {
            if (sqlSession != null){
                MyBatisUtil.close(sqlSession);
            }
        }

    }

2.bug详情

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): pers.lintao.dao.PersonTableDao.queryById

	at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235)
	at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:53)
	at org.apache.ibatis.binding.MapperProxy.lambda$cachedInvoker$0(MapperProxy.java:108)
	at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
	at org.apache.ibatis.util.MapUtil.computeIfAbsent(MapUtil.java:36)
	at org.apache.ibatis.binding.MapperProxy.cachedInvoker(MapperProxy.java:95)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86)
	at com.sun.proxy.$Proxy8.queryById(Unknown Source)
	at QueryTest.testQuery(QueryTest.java:22)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

3.解决bug

修改前:    
	<mappers>
         <package name="pers.lintao.dao"/>
    </mappers>
修改后:   
    <mappers>
        <mapper resource="mappers/PersonTableDao.xml"/>
    </mappers>

4.原因总结

<mappers>标签中的子标签只有mapper,package两种;并且同时只能出现一种(The content of element type "mappers" must match "(mapper*,package*)"):
    <!-- 1.mapper适用于xml文件和接口配合适用,也可以可以不用配置<mapper class="pers.lintao.dao.PersonTableDao"/>,因为在xml映射件中的namespace的值就是接口的全限定名 -->
	<mappers>
        <mapper resource="mappers/PersonTableDao.xml"/>
    </mappers>
    或者(必须接口配置在前)
    <mappers>
    	<mapper class="pers.lintao.dao.PersonTableDao"/>
        <mapper resource="mappers/PersonTableDao.xml"/>
    </mappers>
    <!-- 2.package配置适用于mybatis注解开发 -->
    <mappers>
        <package name="pers.lintao.dao"/>
    </mappers>
    

5.bug拓展

    <!--xml文件在dao层接口之前注册-->
    <mappers>
        <mapper resource="mappers/PersonTableDao.xml"/>
        <mapper class="pers.lintao.dao.PersonTableDao"/>
    </mappers>
就会报以下异常:
Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. 
Cause: org.apache.ibatis.binding.BindingException: 
    Type interface pers.lintao.dao.PersonTableDao is already known to the MapperRegistry.

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值