【问题标题】:How to pass properties to MySQL StatementInterceptor in Java?如何在 Java 中将属性传递给 MySQL StatementInterceptor?
【发布时间】:2018-04-17 14:51:51
【问题描述】:

我正在制作一个自定义 MySQL StatementInterceptorV2,并希望将一些自定义属性传递给它(例如一些任意的Strings)。考虑到语句拦截器是这样创建的(根据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 对象传递自定义属性是唯一的方法吗?

【问题讨论】:

    标签: java mysql aws-xray


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2016-08-01
      • 1970-01-01
      • 2015-06-29
      • 1970-01-01
      • 1970-01-01
      • 2020-04-30
      • 2016-02-28
      • 2015-10-26
      • 1970-01-01
      相关资源
      最近更新 更多