解决mybatis在oracle中null的有关问题

解决mybatis在oracle中null的问题

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

}