BaseExecutor

protected Connection getConnection(Log statementLog) throws SQLException {
Connection connection = transaction.getConnection();
if (statementLog.isDebugEnabled()) {
return ConnectionLogger.newInstance(connection, statementLog, queryStack);
} else {
return connection;
}
}


mybatis-jdbc日志代理类_代理类 


ConnectionLogger

/** Connection日志代理类
* Connection proxy to add logging.
*
* @author Clinton Begin
* @author Eduardo Macarron
*
*/
public final class ConnectionLogger extends BaseJdbcLogger implements InvocationHandler {

private final Connection connection;

private ConnectionLogger(Connection conn, Log statementLog, int queryStack) {
super(statementLog, queryStack);
this.connection = conn;
}

@Override
public Object invoke(Object proxy, Method method, Object[] params)
throws Throwable {
try {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, params);
}
if ("prepareStatement".equals(method.getName())) {
if (isDebugEnabled()) {
debug(" Preparing: " + removeBreakingWhitespace((String) params[0]), true);
}
PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
stmt = PreparedStatementLogger.newInstance(stmt, statementLog, queryStack); // 给PreparedStatement、CallableStatement创建代理类PreparedStatementLogger
return stmt;
} else if ("prepareCall".equals(method.getName())) {
if (isDebugEnabled()) {
debug(" Preparing: " + removeBreakingWhitespace((String) params[0]), true);
}
PreparedStatement stmt = (PreparedStatement) method.invoke(connection, params);
stmt = PreparedStatementLogger.newInstance(stmt, statementLog, queryStack); // 给PreparedStatement、CallableStatement创建代理类PreparedStatementLogger
return stmt;
} else if ("createStatement".equals(method.getName())) {
Statement stmt = (Statement) method.invoke(connection, params);
stmt = StatementLogger.newInstance(stmt, statementLog, queryStack); // 给Statement创建代理类StatementLogger
return stmt;
} else {
return method.invoke(connection, params);
}
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}

/** 创建Connection的代理类
* Creates a logging version of a connection.
*
* @param conn - the original connection
* @return - the connection with logging
*/
public static Connection newInstance(Connection conn, Log statementLog, int queryStack) {
InvocationHandler handler = new ConnectionLogger(conn, statementLog, queryStack);
ClassLoader cl = Connection.class.getClassLoader();
return (Connection) Proxy.newProxyInstance(cl, new Class[]{Connection.class}, handler);
}

/**
* return the wrapped connection.
*
* @return the connection
*/
public Connection getConnection() {
return connection;
}

}


PreparedStatementLogger 

/** PreparedStatement 日志代理类
* PreparedStatement proxy to add logging.
*
* @author Clinton Begin
* @author Eduardo Macarron
*
*/
public final class PreparedStatementLogger extends BaseJdbcLogger implements InvocationHandler {

private final PreparedStatement statement;

private PreparedStatementLogger(PreparedStatement stmt, Log statementLog, int queryStack) {
super(statementLog, queryStack);
this.statement = stmt;
}

@Override
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
try {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, params);
}
if (EXECUTE_METHODS.contains(method.getName())) { // 是否在排除的方法里(execute executeUpdate executeQuery addBatch)
if (isDebugEnabled()) {
debug("Parameters: " + getParameterValueString(), true);
}
clearColumnInfo();
if ("executeQuery".equals(method.getName())) { // executeQuery
ResultSet rs = (ResultSet) method.invoke(statement, params);
return rs == null ? null : ResultSetLogger.newInstance(rs, statementLog, queryStack); // rs不为空,则创建rs代理ResultSetLogger
} else {
return method.invoke(statement, params);
}
} else if (SET_METHODS.contains(method.getName())) {
if ("setNull".equals(method.getName())) {
setColumn(params[0], null);
} else {
setColumn(params[0], params[1]);
}
return method.invoke(statement, params);
} else if ("getResultSet".equals(method.getName())) { // 调用getResultSet
ResultSet rs = (ResultSet) method.invoke(statement, params);
return rs == null ? null : ResultSetLogger.newInstance(rs, statementLog, queryStack); // rs不为空,则创建rs代理ResultSetLogger
} else if ("getUpdateCount".equals(method.getName())) {
int updateCount = (Integer) method.invoke(statement, params);
if (updateCount != -1) {
debug(" Updates: " + updateCount, false);
}
return updateCount;
} else {
return method.invoke(statement, params);
}
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}

/**
* Creates a logging version of a PreparedStatement.
*
* @param stmt - the statement
* @param statementLog - the statement log
* @param queryStack - the query stack
* @return - the proxy
*/
public static PreparedStatement newInstance(PreparedStatement stmt, Log statementLog, int queryStack) {
InvocationHandler handler = new PreparedStatementLogger(stmt, statementLog, queryStack);
ClassLoader cl = PreparedStatement.class.getClassLoader();
return (PreparedStatement) Proxy.newProxyInstance(cl, new Class[]{PreparedStatement.class, CallableStatement.class}, handler);
}

/**
* Return the wrapped prepared statement.
*
* @return the PreparedStatement
*/
public PreparedStatement getPreparedStatement() {
return statement;
}

}

ResultSetLogger 

/** ResultSet日志代理类
* ResultSet proxy to add logging.
*
* @author Clinton Begin
* @author Eduardo Macarron
*
*/
public final class ResultSetLogger extends BaseJdbcLogger implements InvocationHandler {

private static final Set<Integer> BLOB_TYPES = new HashSet<>();
private boolean first = true;
private int rows;
private final ResultSet rs;
private final Set<Integer> blobColumns = new HashSet<>();

static {
BLOB_TYPES.add(Types.BINARY);
BLOB_TYPES.add(Types.BLOB);
BLOB_TYPES.add(Types.CLOB);
BLOB_TYPES.add(Types.LONGNVARCHAR);
BLOB_TYPES.add(Types.LONGVARBINARY);
BLOB_TYPES.add(Types.LONGVARCHAR);
BLOB_TYPES.add(Types.NCLOB);
BLOB_TYPES.add(Types.VARBINARY);
}

private ResultSetLogger(ResultSet rs, Log statementLog, int queryStack) {
super(statementLog, queryStack);
this.rs = rs;
}

@Override
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
try {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, params);
}
Object o = method.invoke(rs, params);
if ("next".equals(method.getName())) {
if ((Boolean) o) {
rows++;
if (isTraceEnabled()) {
ResultSetMetaData rsmd = rs.getMetaData();
final int columnCount = rsmd.getColumnCount();
if (first) {
first = false;
printColumnHeaders(rsmd, columnCount);
}
printColumnValues(columnCount);
}
} else {
debug(" Total: " + rows, false);
}
}
clearColumnInfo();
return o;
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}

private void printColumnHeaders(ResultSetMetaData rsmd, int columnCount) throws SQLException {
StringJoiner row = new StringJoiner(", ", " Columns: ", "");
for (int i = 1; i <= columnCount; i++) {
if (BLOB_TYPES.contains(rsmd.getColumnType(i))) {
blobColumns.add(i);
}
row.add(rsmd.getColumnLabel(i));
}
trace(row.toString(), false);
}

private void printColumnValues(int columnCount) {
StringJoiner row = new StringJoiner(", ", " Row: ", "");
for (int i = 1; i <= columnCount; i++) {
try {
if (blobColumns.contains(i)) {
row.add("<<BLOB>>");
} else {
row.add(rs.getString(i));
}
} catch (SQLException e) {
// generally can't call getString() on a BLOB column
row.add("<<Cannot Display>>");
}
}
trace(row.toString(), false);
}

/**
* Creates a logging version of a ResultSet.
*
* @param rs - the ResultSet to proxy
* @return - the ResultSet with logging
*/
public static ResultSet newInstance(ResultSet rs, Log statementLog, int queryStack) {
InvocationHandler handler = new ResultSetLogger(rs, statementLog, queryStack);
ClassLoader cl = ResultSet.class.getClassLoader();
return (ResultSet) Proxy.newProxyInstance(cl, new Class[]{ResultSet.class}, handler);
}

/**
* Get the wrapped result set.
*
* @return the resultSet
*/
public ResultSet getRs() {
return rs;
}

}

StatementLogger 

/** Statement日志代理类
* Statement proxy to add logging.
*
* @author Clinton Begin
* @author Eduardo Macarron
*
*/
public final class StatementLogger extends BaseJdbcLogger implements InvocationHandler {

private final Statement statement;

private StatementLogger(Statement stmt, Log statementLog, int queryStack) {
super(statementLog, queryStack);
this.statement = stmt;
}

@Override
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
try {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, params);
}
if (EXECUTE_METHODS.contains(method.getName())) { // 是否在排除的方法里(execute executeUpdate executeQuery addBatch)
if (isDebugEnabled()) {
debug(" Executing: " + removeBreakingWhitespace((String) params[0]), true);
}
if ("executeQuery".equals(method.getName())) {
ResultSet rs = (ResultSet) method.invoke(statement, params);
return rs == null ? null : ResultSetLogger.newInstance(rs, statementLog, queryStack); // rs不为空,则创建rs代理ResultSetLogger
} else {
return method.invoke(statement, params);
}
} else if ("getResultSet".equals(method.getName())) {
ResultSet rs = (ResultSet) method.invoke(statement, params);
return rs == null ? null : ResultSetLogger.newInstance(rs, statementLog, queryStack); // rs不为空,则创建rs代理ResultSetLogger
} else {
return method.invoke(statement, params);
}
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}

/**
* Creates a logging version of a Statement.
*
* @param stmt - the statement
* @return - the proxy
*/
public static Statement newInstance(Statement stmt, Log statementLog, int queryStack) {
InvocationHandler handler = new StatementLogger(stmt, statementLog, queryStack);
ClassLoader cl = Statement.class.getClassLoader();
return (Statement) Proxy.newProxyInstance(cl, new Class[]{Statement.class}, handler);
}

/**
* return the wrapped statement.
*
* @return the statement
*/
public Statement getStatement() {
return statement;
}

}