最近在学习mybatis的一二级缓存时,根据网上视频使用select查询语句操作遇到的一些问题,我是单独用mybaits(版本3.5.1)的测试时(没有和spring集成),遇到如下报错:
Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for 你的项目中mapper的接口方法。报错的意思是说在mapper.xml中没有找到mapper接口中的方法。
通过在网上寻找解决方法时,根据踩坑经历总结的方法如下:
(1)mapper的xml文件中是否配置了namespace,配置是否正确(需要写到类名),同时保证mapper.java和mapper.xml的文件名相同。如我的项目中使用如截图。
(2)mapper.xml文件中方法的id与mapper接口文件中的方法名一致,方法名不能重复。
(3)mapper.xml文件方法的resultType,resultMap等参数配置是否正确。
(4)在项目中创建mapper接口和mapper.xml的文件是否在同一目录。因为两者文件在同一目录和不同目录的配置是有差异的。我就是在这问题上找了好久的blog才解决。
如果两者文件在同一目录,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"/>
<settings>
<!-- 打印mybatis执行的日志信息-->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<!-- 通过包扫描的方式配置别名 -->
<typeAliases>
<package name="com.tfq.springaop.entity"></package>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!-- UNPOOLED是没有数据库连接池的,每执行一次操作,打开一次数据库,关闭一次数据库.效率较为低下
POOLED是存在数据库连接池的,没有操作数据库从数据库连接池中拿取连接
JNDI这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上
-->
<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>
<!-- mapper映射器,映射包下所有接口(较为常用)-->
<mappers>
<!-- 扫描包下的接口文件 -->
<package name="com.tfq.springaop.dao"/>
</mappers>
</configuration>
我的项目的结构如下:
如果你的mapper接口和mapper.xml的文件不在同一目录,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"/>
<!-- 打印mybatis执行的日志信息-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<!-- 通过包扫描的方式配置别名 -->
<typeAliases>
<package name="com.tfq.springaop.entity"></package>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!-- UNPOOLED是没有数据库连接池的,每执行一次操作,打开一次数据库,关闭一次数据库.效率较为低下
POOLED是存在数据库连接池的,没有操作数据库从数据库连接池中拿取连接
JNDI这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上
-->
<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>
<!-- mapper映射器,映射包下所有接口(较为常用)-->
<mappers>
<!-- 扫描路径下的mapper映射文件 -->
<mapper resource="com/tfq/springaop/mapper/UserMapper.xml"/>
</mappers>
</configuration>
我的项目的结构如下:
如果mapper.xml文件在src/main/java目录下,由于maven默认在此目录下不打包xml文件,所以在pom.xml中要配置如下代码:
<build>
<resources>
<!-- maven把java文件夹下的代码打包到class文件目录 -->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
我的测试类代码:
package com.tfq.springaop;
import java.io.IOException;
import java.io.InputStream;
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.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.tfq.springaop.controller.CarController;
import com.tfq.springaop.entity.User;
/**
*
* @description 测试mybatis的一二级缓存demo
* @author tangfq;
* @version 2020年6月20日 下午12:05:48
*
**/
public class TestMybatis {
private static Logger logger = LoggerFactory.getLogger(TestMybatis.class);
@Test
public void test() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
SqlSession sqlSession=sqlSessionFactory.openSession();
User u1=sqlSession.selectOne("com.tfq.springaop.dao.UserMapper.getById",1);
logger.info("打印对象u1,{}",u1);
System.out.println("打印对象u1="+u1);
User u2=sqlSession.selectOne("com.tfq.springaop.dao.UserMapper.getById",1);
logger.info("打印对象u2,{}",u2);
System.out.println("打印对象u2="+u2);
}
}
执行结果如下:
以上为单独使用mybatis的总结。如果写得有纰漏之处,请大家留言指正。