如何在java中向mysql语句拦截器传递属性?

kyks70gy  于 2021-06-25  发布在  Mysql
关注(0)|答案(1)|浏览(408)

我在做一个定制的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 唯一的办法是什么?

6psbrbz9

6psbrbz91#

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

相关问题