1

我正在制作一个自定义 MySQL StatementInterceptorV2,并希望将一些自定义属性传递给它(例如一些任意String的 s)。考虑到语句拦截器是这样创建的(根据https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-configuration-properties.html):

public Connection getDatabaseConnection(String jdbcUrl, String dbUser, String dbPassword) throws SQLException
{
    Properties dbProps = new Properties();

    dbProps.put("statementInterceptors", "package.path.to.ConnectionInterceptor");
    dbProps.put("user", dbUser);
    dbProps.put("password", dbPassword);

    return DriverManager.getConnection(jdbcUrl, dbProps);
}

我如何将值传递给它?我显然没有调用构造函数或任何东西,这将是做这样的事情的正常方式。这是我的语句拦截器,如果它有帮助的话。

public class ConnectionInterceptor implements StatementInterceptorV2
{
    @Override
    public void init(Connection conn, Properties props) throws SQLException {

    }

    @Override
    public ResultSetInternalMethods preProcess(String sql,
                                               Statement interceptedStatement,
                                               Connection connection) throws SQLException {

        Subsegment subsegment = AWSXRay.beginSubsegment(connection.getHost());

        subsegment.putSql("url", connection.getHost());
        String user = connection.getProperties().getProperty("user");
        if(user != null) {
            subsegment.putSql("user", user);
        }
        subsegment.putSql("database_type", connection.getMetaData().getDatabaseProductName());
        subsegment.putSql("database_version", connection.getMetaData().getDatabaseProductVersion());
        subsegment.putSql("driver_version", connection.getMetaData().getDriverVersion());

        String finalSql = sql;
        // SQL is null in a prepared statement, so we have to grab the SQL from the statement itself
        if(interceptedStatement instanceof PreparedStatement) {
            finalSql = ((PreparedStatement) interceptedStatement).getPreparedSql();
        }
        subsegment.putSql("sanitized_query", finalSql);
        subsegment.setNamespace(Namespace.REMOTE.toString());

        // Return null to return ResultSet as is, without modification
        return null;
    }

    @Override
    public boolean executeTopLevelOnly() {
        return false;
    }

    @Override
    public void destroy() {

    }

    @Override
    public ResultSetInternalMethods postProcess(String sql,
                                                Statement interceptedStatement,
                                                ResultSetInternalMethods originalResultSet,
                                                Connection connection,
                                                int warningCount,
                                                boolean noIndexUsed,
                                                boolean noGoodIndexUsed,
                                                SQLException statementException) throws SQLException {
        AWSXRay.endSubsegment();

        // Return null to return ResultSet as is, without modification
        return null;
    }
}

通过Properties对象传递自定义属性是唯一的方法吗?

4

1 回答 1

1

您可以创建一个名为 ConnectionInterceptorParameters 的新类,它具有静态线程局部参数。您可以在进行 sql 调用之前在业务逻辑中填充本地线程,并且拦截器可以使用这些值。然后,您必须在完成调用后清除 threadlocal。

于 2018-04-18T15:18:43.727 回答