使用myBatis調用存儲過程的返回值,提示錯誤信息:
org.apache.ibatis.binding.BindingException: Mapper method 'com.xxxx.other.dao.MyDao.getNo attempted to return null from a method with a primitive return type (int).
先查mysql監控語句,發現存儲過程調用正常,也得到了返回值,繼續查
對應的文件
存儲過程:
CREATE PROCEDURE `Get_Table_Flow_No`(IN `輸入表名` VARCHAR(100), IN `待取數` INT, OUT `輸出要取的最大流水號` INT)
BEGIN
DECLARE `willRetNo` INT;
SET `輸出要取的最大流水號` = 0 ;
SELECT 字段_已取最大流水號 INTO `willRetNo` FROM 流水號保存表 WHERE 字段_表名=`輸入表名` for UPDATE;
IF `willRetNo` IS NULL THEN
SET `willRetNo` = `待取數` ;
INSERT INTO `流水號保存表`
(字段_表名,字段_已取最大流水號,字段_上次獲取時間)
VALUES (`輸入表名`, `willRetNo`, NOW());
ELSE
SET `willRetNo` = `willRetNo` + `待取數` ;
UPDATE `流水號保存表`
SET 字段_已取最大流水號 = `willRetNo`
, 字段_上次獲取時間 = NOW()
WHERE 字段_表名=`輸入表名` ;
END IF;
SET `輸出要取的最大流水號` = `willRetNo`;
END
MyDao.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.xxxx.other.dao.MyDao">
<parameterMap type="java.util.Map" id = "FlowNoMap">
<parameter property="輸入表名" mode="IN" jdbcType="VARCHAR"/>
<parameter property="待取數" mode="IN" jdbcType="INTEGER"/>
<parameter property="返回最大數值" mode="OUT" jdbcType="INTEGER"/>
</parameterMap>
<select id="getFlowNo" parameterMap="FlowNoMap" statementType="CALLABLE">
<if test="_databaseId == 'mysql'">
call Get_Table_Flow_No(#{輸入表名 ,jdbcType=VARCHAR,mode=IN},#{待取數,jdbcType=INTEGER,mode=IN},#{返回最大數值 ,jdbcType=INTEGER,mode=OUT});
</if>
<if test="_databaseId == 'sqlserver'"></if>
</select>
</mapper>
MyDao.java
package com.xxxx.other.dao;
import org.apache.ibatis.annotations.Param;
import org.springframework.dao.DataAccessException;
import java.util.List;
import java.util.Map;
public interface MyDao {
int getNo(Map<String, Object> parameterMap) throws DataAccessException;
}
錯誤信息出在:
org/apache/ibatis/binding/MapperMethod.java 方法 execute 中
if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
throw new BindingException("Mapper method '" + command.getName()
+ " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
}
因為result 為 null,所以拋出了異常,往上推,同文件中
else if (SqlCommandType.SELECT == command.getType()) {
if (method.returnsVoid() && method.hasResultHandler()) {
executeWithResultHandler(sqlSession, args);
result = null;
} else if (method.returnsMany()) {
result = executeForMany(sqlSession, args);
} else if (method.returnsMap()) {
result = executeForMap(sqlSession, args);
} else {
Object param = method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(command.getName(), param);
}
}
調用的是最后一個條件:
Object param = method.convertArgsToSqlCommandParam(args); result = sqlSession.selectOne(command.getName(), param);
調用的存儲過程中,只是把值通過輸出參數返回出來,沒提供select語句,所以result為空,但param中有對"返回最大數值"取到值
再返回報錯的地方,看到有驗證條件: !method.returnsVoid() ,實際在myDao.xml中是沒有返回的,查詢 MyDao.java,
接口中有返回值: int getNo(Map<String, Object> parameterMap) throws DataAccessException;
把 int 調整為 void, 程序運行正常,通過 parameterMap 取到了最大數
