IDEA maven项目下测试mybatis例子,使用mappper class或package引入mapper映射文件,总是报错Invalid bound statement(所有配置完全正确)
困扰几个小时,终于查到解决办法及原因(可以直接到最后看解决方案)
环境就是用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>
项目结构如下
PO类User代码省略,下面是接口UserMapper代码
package com.hjp.mapper; import com.hjp.po.User; public interface UserMapper { User findUserById(int id) throws Exception; }
映射文件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(); } }
运行测试代码,报错信息如下
检查了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接口一致,而且要在同一个目录下