首页 > 技术文章 > IDEA maven项目下测试mybatis例子,使用mappper class或package引入mapper映射文件,总是报错Invalid bound statement(所有配置完全正确)

hujiapeng 2017-06-29 11:31 原文

困扰几个小时,终于查到解决办法及原因(可以直接到最后看解决方案)

环境就是用IDEA搭建的maven项目,主要jar包引入配置如下

<dependencies>
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>5.1.6</version>
       </dependency>
       <dependency>
           <groupId>org.mybatis</groupId>
           <artifactId>mybatis</artifactId>
           <version>3.4.1</version>
       </dependency>
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.12</version>
           <scope>test</scope>
       </dependency>

       <dependency>
           <groupId>commons-logging</groupId>
           <artifactId>commons-logging</artifactId>
           <version>1.1.1</version>
       </dependency>

       <dependency>
           <groupId>org.apache.logging.log4j</groupId>
           <artifactId>log4j-api</artifactId>
           <version>2.6.2</version>
       </dependency>
       <dependency>
           <groupId>org.apache.logging.log4j</groupId>
           <artifactId>log4j-core</artifactId>
           <version>2.6.2</version>
       </dependency>
   </dependencies>
maven mybatis依赖包

项目结构如下

PO类User代码省略,下面是接口UserMapper代码

package com.hjp.mapper;

import com.hjp.po.User;

public interface UserMapper {

    User findUserById(int id) throws Exception;

}
UserMapper.java

映射文件UserMapper.xml配置如下

<?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="com.hjp.mapper.UserMapper">
    <select id="findUserById" parameterType="int" resultType="User">
        SELECT * FROM USER WHERE id=#{id}
    </select>
</mapper>

log4j.properties和db.properties文件配置省略,mybatis全局配置文件sqlMapConfig.xml配置如下(采用package批量映射,要求mapper映射文件要和mapper接口放在同一个包下)

<?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="db.properties"></properties>
    <typeAliases>
        <package name="com.hjp.po"></package>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${db.driver}"></property>
                <property name="url" value="${db.url}"></property>
                <property name="username" value="${db.username}"></property>
                <property name="password" value="${db.password}"></property>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <package name="com.hjp.mapper" />
    </mappers>
</configuration>

测试类代码如下

import com.hjp.mapper.UserMapper;
import com.hjp.po.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;

public class MapperTest {

    SqlSessionFactory factory;

    @Before
    public void setUp() throws IOException {
        String resource="sqlMapConfig.xml";
        InputStream inputStream= Resources.getResourceAsStream(resource);
        factory=new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void func1() throws Exception {
        SqlSession session=factory.openSession();
        UserMapper userMapper=session.getMapper(UserMapper.class);
        User user=userMapper.findUserById(1);
        System.out.println(user);
        session.close();
    }

}
MapperTest.java

运行测试代码,报错信息如下

检查了n遍配置和代码,没有发现问题,而且使用mapper的resource单独配置指向resources文件夹下mapper映射文件(如图)就没问题

 

 后来想到是解析xml的问题,到编译后的文件夹下查看,没有UserMapper.xml文件

 

然后找解决方案,原来是IDEA maven项目默认不会把src下除java文件外的文件打包到classes文件夹下,需要配置如下

 <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <!--默认是true-->
                <!--<filtering>true</filtering>-->
            </resource>
        </resources>
    </build>

或者手动把文件拷贝到classes文件夹对应的目录下,结果如下图

 注意:如果不具体指定到mapper的xml文件,要确保mapper的xml文件前缀名和对应的Mapper接口一致,而且要在同一个目录下

推荐阅读