最近在學習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的總結。如果寫得有紕漏之處,請大家留言指正。