使用mybatis时遇到Error setting null parameter异常,常用的解决方式是在sql中指定jdbcType,这样的写法感觉有点罗嗦,后来参考spring jdbc中的实现方式,改写了mybatis中的BaseTypeHandler类,经测试ok。
以下是修改的类文件,修改的地方为19 ~ 36行。
package org.apache.ibatis.type;
import java.sql.CallableStatement;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
public abstract class BaseTypeHandler implements TypeHandler {
public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
if (parameter == null) {
if (jdbcType == null) {
try {
boolean useSetObject = false;
int sqlType = Types.NULL;
try {
DatabaseMetaData dbmd = ps.getConnection().getMetaData();
String databaseProductName = dbmd.getDatabaseProductName();
String jdbcDriverName = dbmd.getDriverName();
if (databaseProductName.startsWith("Informix")
|| jdbcDriverName.startsWith("Microsoft SQL Server")) {
useSetObject = true;
} else if (databaseProductName.startsWith("Oracle") || databaseProductName.startsWith("DB2") || jdbcDriverName.startsWith("jConnect")
|| jdbcDriverName.startsWith("SQLServer") || jdbcDriverName.startsWith("Apache Derby")) {
sqlType = Types.VARCHAR;
}
} catch (Throwable ex) {
throw new TypeException("Could not check database or driver name", ex);
}
if (useSetObject) {
ps.setObject(i, null);
} else {
ps.setNull(i, sqlType);
}
} catch (SQLException e) {
throw new TypeException(
"Error setting null parameter. Most JDBC drivers require that the JdbcType must be specified for all nullable parameters. Cause: "
+ e, e);
}
} else {
ps.setNull(i, jdbcType.TYPE_CODE);
}
} else {
setNonNullParameter(ps, i, parameter, jdbcType);
}
}
public Object getResult(ResultSet rs, String columnName) throws SQLException {
Object result = getNullableResult(rs, columnName);
if (rs.wasNull()) {
return null;
} else {
return result;
}
}
public Object getResult(CallableStatement cs, int columnIndex) throws SQLException {
Object result = getNullableResult(cs, columnIndex);
if (cs.wasNull()) {
return null;
} else {
return result;
}
}
public abstract void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
throws SQLException;
public abstract Object getNullableResult(ResultSet rs, String columnName) throws SQLException;
public abstract Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException;
}