mybatis异常时如何获取参数

时间:2014-10-23 07:23:50

标签: exception parameters mybatis

对不起。我不能很好地写英文。

这是我的mybatis错误消息(e.getMessage())

### Error updating database.  Cause: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'name' at row 1
### The error may involve default.user-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO USER (name) VALUES (?)
### Cause: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'name'
at row 1; SQL []; Data truncation: Data too long for column 'name' at row 1; nested exception is
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'name' at row 1

我想在发生异常时知道参数。

SQL:INSERT INTO USER(name)VALUES(?)>>我希望得到这个问题的价值。

我试试这段代码

    try {
        sqlSessionTemplate.insert("namespace.id", parameter);
    } catch (Exception e) {
        if (e instanceof BadSqlGrammarException) {
            logger.error("{}", e.getMessage());
        } else if (e instanceof DataIntegrityViolationException) {
            logger.error("{}", e.getMessage());             
        } else if (e instanceof MysqlDataTruncation) {
            logger.error("{}", e.getMessage());             
        }
    }
  

DataIntegrityViolationException MysqlDataTruncation 不支持获取错误参数。

这是一个示例,我想知道在Exception中获取参数(对象)。

你能给我一些解决这个问题的建议吗?谢谢。

2 个答案:

答案 0 :(得分:0)

在MyBatis中设置logging并将其设置为TRACE级别。这样,您将在日志文件中写入完整的INSERT语句(使用实际使用的参数)。

答案 1 :(得分:0)

你可以写一个mybatis的插件,如下所示:

@Intercepts({ @Signature(type = ParameterHandler.class, method = "setParameters", args = { PreparedStatement.class }) })

public class SQLErrorContextInterceptor implements Interceptor {

private final ILogger logger = new LoggerImpl(this.getClass());

@Override

public Object intercept(Invocation invocation) throws Throwable {

    invocation.proceed();

    Object target=invocation.getTarget();

    if( ! (target instanceof  DefaultParameterHandler) ){

        return null;

    }

    DefaultParameterHandler hander=(DefaultParameterHandler)target;

    //obtains 5 fields from DefaultParameterHandler object

    Class<?> clz =hander.getClass();

    Field f = clz.getDeclaredField("mappedStatement");

    f.setAccessible(true);

    MappedStatement mappedStatement=(MappedStatement)f.get(hander);

    Configuration configuration = mappedStatement.getConfiguration();

    TypeHandlerRegistry typeHandlerRegistry=mappedStatement.getConfiguration().getTypeHandlerRegistry();

    f=clz.getDeclaredField("boundSql");

    f.setAccessible(true);

    BoundSql boundSql=(BoundSql)f.get(hander);

    Object parameterObject=hander.getParameterObject();



    //used to stored parameters values order by sql parameters 

    List<Object> columnValues = new ArrayList<Object>();



    // get parameters'value  by for-each

    List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();

    if (parameterMappings != null) {

      MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);

      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 {

            value = metaObject == null ? null : metaObject.getValue(propertyName);

          }

          columnValues.add(value);

        }

      }

    }

    // overwrite sql's context in ErrorContext, and  append  parameters's value-str

    ErrorContext.instance().sql(boundSql.getSql() + " parameters:" + this.getParameterValueString(columnValues));

    return null;

}





private  String getParameterValueString(List<Object> columnValues) {

    List<Object> typeList = new ArrayList<Object>(columnValues.size());

    for (Object value : columnValues) {

      if (value == null) {

        typeList.add("null");

      } else {

        typeList.add(value + "(" + value.getClass().getSimpleName() + ")");

      }

    }

    final String parameters = typeList.toString();

    return parameters.substring(1, parameters.length() - 1);

  }



@Override

public Object plugin(Object target) {

    return Plugin.wrap(target, this);

}



@Override

public void setProperties(Properties properties) {



}


}