Mybatis自带的日志没有把可执行sql语句打印出来,跟踪了一下其参数替换流程记录下来,详细的参数替换原理可以参考大牛的博文《深入了解MyBatis参数》
下面是字符串参数替换的流程,红色标注部分为主要赋值函数
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException { Connection connection = this.getConnection(statementLog); Statement stmt = handler.prepare(connection, this.transaction.getTimeout()); handler.parameterize(stmt); return stmt; }
public void parameterize(Statement statement) throws SQLException { this.delegate.parameterize(statement); }
public void parameterize(Statement statement) throws SQLException { this.parameterHandler.setParameters((PreparedStatement)statement); }
public void setParameters(PreparedStatement ps) { ErrorContext.instance().activity("setting parameters").object(this.mappedStatement.getParameterMap().getId()); List parameterMappings = this.boundSql.getParameterMappings(); if(parameterMappings != null) { for(int i = 0; i < parameterMappings.size(); ++i) { ParameterMapping parameterMapping = (ParameterMapping)parameterMappings.get(i); if(parameterMapping.getMode() != ParameterMode.OUT) { String propertyName = parameterMapping.getProperty(); Object value; if(this.boundSql.hasAdditionalParameter(propertyName)) { value = this.boundSql.getAdditionalParameter(propertyName); } else if(this.parameterObject == null) { value = null; } else if(this.typeHandlerRegistry.hasTypeHandler(this.parameterObject.getClass())) { value = this.parameterObject; } else { MetaObject typeHandler = this.configuration.newMetaObject(this.parameterObject); value = typeHandler.getValue(propertyName); } TypeHandler var12 = parameterMapping.getTypeHandler(); JdbcType jdbcType = parameterMapping.getJdbcType(); if(value == null && jdbcType == null) { jdbcType = this.configuration.getJdbcTypeForNull(); } try { var12.setParameter(ps, i + 1, value, jdbcType); } catch (TypeException var10) { throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + var10, var10); } catch (SQLException var11) { throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + var11, var11); } } } } }5.org.apache.ibatis.type.BaseTypeHandler
public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException { if(parameter == null) { if(jdbcType == null) { throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters."); } try { ps.setNull(i, jdbcType.TYPE_CODE); } catch (SQLException var7) { throw new TypeException("Error setting null for parameter #" + i + " with JdbcType " + jdbcType + " . " + "Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. " + "Cause: " + var7, var7); } } else { try { this.setNonNullParameter(ps, i, parameter, jdbcType); } catch (Exception var6) { throw new TypeException("Error setting non null for parameter #" + i + " with JdbcType " + jdbcType + " . " + "Try setting a different JdbcType for this parameter or a different configuration property. " + "Cause: " + var6, var6); } } }
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException { TypeHandler handler = this.resolveTypeHandler(parameter, jdbcType); handler.setParameter(ps, i, parameter, jdbcType); }
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter); }
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable { try { if(Object.class.equals(method.getDeclaringClass())) { return method.invoke(this, params); } else { ResultSet t1; if(EXECUTE_METHODS.contains(method.getName())) { if(this.isDebugEnabled()) { this.debug("Parameters: " + this.getParameterValueString(), true); } this.clearColumnInfo(); if("executeQuery".equals(method.getName())) { t1 = (ResultSet)method.invoke(this.statement, params); return t1 == null?null:ResultSetLogger.newInstance(t1, this.statementLog, this.queryStack); } else { return method.invoke(this.statement, params); } } else if(SET_METHODS.contains(method.getName())) { if("setNull".equals(method.getName())) { this.setColumn(params[0], (Object)null); } else { this.setColumn(params[0], params[1]); } return method.invoke(this.statement, params); } else if("getResultSet".equals(method.getName())) { t1 = (ResultSet)method.invoke(this.statement, params); return t1 == null?null:ResultSetLogger.newInstance(t1, this.statementLog, this.queryStack); } else if("getUpdateCount".equals(method.getName())) { int t = ((Integer)method.invoke(this.statement, params)).intValue(); if(t != -1) { this.debug(" Updates: " + t, false); } return Integer.valueOf(t); } else { return method.invoke(this.statement, params); } } } catch (Throwable var5) { throw ExceptionUtil.unwrapThrowable(var5); } }