使用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;
}