Mybatis传值为空需要配置JdbcType来解决吗?(XML文件不需要配置JdbcType)

时间:2023-03-09 17:47:55
Mybatis传值为空需要配置JdbcType来解决吗?(XML文件不需要配置JdbcType)

1,解决思路,配置自定义的语言驱动,重写自己的Paramethander

 package cn.com.servyou.gxdqy.tool.xmlhelper;

 import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver; /**
* @author : hao
* @project : daieweb
* @description : 自定义的 jdbcType 语言驱动
* @time : 2018/10/12 16:00
*/
public class JdbcTypeLanguageDriver extends XMLLanguageDriver {
public JdbcTypeLanguageDriver() {
} @Override
public ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
return new JdbcTypeDefaultParameterHandler(mappedStatement, parameterObject, boundSql);
}
}
 package cn.com.servyou.gxdqy.tool.xmlhelper;

 import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeException;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry; import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* @author : hao
* @project : daieweb
* @description : 参数处理器 负责把值为空且jdbcType为空的 初始化 jdbcType
* @time : 2018/10/12 16:01
*/
public class JdbcTypeDefaultParameterHandler extends DefaultParameterHandler { private final TypeHandlerRegistry typeHandlerRegistry;
private final MappedStatement mappedStatement;
private final Object parameterObject;
private BoundSql boundSql;
private Configuration configuration;
public static Map<Class<?>, JdbcType> typeMap = new HashMap(); static { //设置默认的类型转换,参考 TypeHandlerRegistry
register(Boolean.class, JdbcType.BOOLEAN);
register(boolean.class, JdbcType.BOOLEAN); register(Byte.class, JdbcType.TINYINT);
register(byte.class, JdbcType.TINYINT); register(Short.class, JdbcType.SMALLINT);
register(short.class, JdbcType.SMALLINT); register(Integer.class, JdbcType.INTEGER);
register(int.class, JdbcType.INTEGER); register(Long.class, JdbcType.BIGINT);
register(long.class, JdbcType.BIGINT); register(Float.class, JdbcType.FLOAT);
register(float.class, JdbcType.FLOAT); register(Double.class, JdbcType.DOUBLE);
register(double.class, JdbcType.DOUBLE); register(String.class, JdbcType.VARCHAR); register(BigDecimal.class, JdbcType.DECIMAL);
register(BigInteger.class, JdbcType.DECIMAL); register(Byte[].class, JdbcType.BLOB);
register(byte[].class, JdbcType.BLOB); register(Date.class, JdbcType.DATE);
register(java.sql.Date.class, JdbcType.DATE);
register(java.sql.Time.class, JdbcType.TIME);
register(java.sql.Timestamp.class, JdbcType.TIMESTAMP); register(Character.class, JdbcType.CHAR);
register(char.class, JdbcType.CHAR);
} public JdbcTypeDefaultParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
super(mappedStatement, parameterObject, boundSql); this.mappedStatement = mappedStatement;
this.configuration = mappedStatement.getConfiguration();
this.typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry();
this.parameterObject = parameterObject;
this.boundSql = boundSql;
} /**
* 重写 方法 设置默认值
* @param ps
*/
@Override
public void setParameters(PreparedStatement ps) {
ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
if (parameterMappings != null) {
for (int i = 0; i < parameterMappings.size(); i++) {
ParameterMapping parameterMapping = parameterMappings.get(i);
if (parameterMapping.getMode() != ParameterMode.OUT) {
Object value;
String propertyName = parameterMapping.getProperty();
if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params
value = boundSql.getAdditionalParameter(propertyName);
} else if (parameterObject == null) {
value = null;
} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
value = parameterObject;
} else {
MetaObject metaObject = configuration.newMetaObject(parameterObject);
value = metaObject.getValue(propertyName);
}
TypeHandler typeHandler = parameterMapping.getTypeHandler();
JdbcType jdbcType = parameterMapping.getJdbcType();
if (value == null && jdbcType == null) {
if (parameterMapping.getJavaType() != null && typeMap.containsKey(parameterMapping.getJavaType())) {
jdbcType = typeMap.get(parameterMapping.getJavaType());
} else {
jdbcType = configuration.getJdbcTypeForNull();
}
}
try {
typeHandler.setParameter(ps, i + 1, value, jdbcType);
} catch (TypeException e) {
throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
} catch (SQLException e) {
throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
}
}
}
}
} public static void register(String type, String jdbcType) {
try {
typeMap.put(Class.forName(type), JdbcType.valueOf(jdbcType));
} catch (ClassNotFoundException e) {
throw new RuntimeException("配置 typeMaps 时出错!", e);
}
} public static void register(Class<?> type, JdbcType jdbcType) {
typeMap.put(type, jdbcType);
}
}

Mybatis传值为空需要配置JdbcType来解决吗?(XML文件不需要配置JdbcType)