CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-mysql--mysql-connector-j

JDBC Type 4 driver for MySQL with X DevAPI support for document store operations

Overview
Eval results
Files

interceptors.mddocs/

Interceptors

Query and connection lifecycle interceptors for customizing driver behavior. Interceptors allow you to hook into query execution and connection events.

Capabilities

Query Interceptor

Interface for intercepting query execution.

package com.mysql.cj.interceptors;

public interface QueryInterceptor {
    // Initialize interceptor
    QueryInterceptor init(MysqlConnection conn, Properties props, Log log);

    // Pre-process query (before execution)
    <T extends Resultset> T preProcess(Supplier<String> sql, Query interceptedQuery);

    // Check if should execute only at top level
    boolean executeTopLevelOnly();

    // Destroy interceptor
    void destroy();

    // Post-process query (after execution)
    <T extends Resultset> T postProcess(Supplier<String> sql, Query interceptedQuery,
                                       T originalResultSet, ServerSession serverSession);
}

Usage:

// Implement custom query interceptor
public class MyQueryInterceptor implements QueryInterceptor {
    private Log log;

    public QueryInterceptor init(MysqlConnection conn, Properties props, Log log) {
        this.log = log;
        return this;
    }

    public <T extends Resultset> T preProcess(Supplier<String> sql, Query interceptedQuery) {
        log.logInfo("Executing query: " + sql.get());
        return null;  // null means proceed with execution
    }

    public boolean executeTopLevelOnly() {
        return false;  // Also intercept nested queries
    }

    public void destroy() {
        // Cleanup
    }

    public <T extends Resultset> T postProcess(Supplier<String> sql, Query interceptedQuery,
                                              T originalResultSet, ServerSession serverSession) {
        log.logInfo("Query completed: " + sql.get());
        return originalResultSet;
    }
}

// Configure interceptor in URL
String url = "jdbc:mysql://localhost:3306/mydb" +
             "?queryInterceptors=com.mycompany.MyQueryInterceptor";
Connection conn = DriverManager.getConnection(url, "user", "pass");

// All queries will be intercepted
Statement stmt = conn.createStatement();
stmt.executeQuery("SELECT * FROM users");

Connection Lifecycle Interceptor

Interface for intercepting connection lifecycle events.

package com.mysql.cj.jdbc.interceptors;

public interface ConnectionLifecycleInterceptor {
    // Initialize interceptor
    ConnectionLifecycleInterceptor init(MysqlConnection conn, Properties props, Log log);

    // Destroy interceptor
    void destroy();

    // Called when new session is created
    void createNewSession();

    // Called when transaction begins
    void transactionBegun();

    // Called when transaction completes (commit or rollback)
    void transactionCompleted();
}

Usage:

// Implement custom connection lifecycle interceptor
public class MyConnectionLifecycleInterceptor implements ConnectionLifecycleInterceptor {
    private Log log;

    public ConnectionLifecycleInterceptor init(MysqlConnection conn, Properties props, Log log) {
        this.log = log;
        return this;
    }

    public void destroy() {
        // Cleanup
    }

    public void createNewSession() {
        log.logInfo("New database session created");
    }

    public void transactionBegun() {
        log.logInfo("Transaction started");
    }

    public void transactionCompleted() {
        log.logInfo("Transaction completed");
    }
}

// Configure interceptor in URL
String url = "jdbc:mysql://localhost:3306/mydb" +
             "?connectionLifecycleInterceptors=com.mycompany.MyConnectionLifecycleInterceptor";
Connection conn = DriverManager.getConnection(url, "user", "pass");

// Lifecycle events will be intercepted
conn.setAutoCommit(false);  // transactionBegun() called
stmt.executeUpdate("INSERT INTO users (name) VALUES ('Alice')");
conn.commit();  // transactionCompleted() called

Result Set Scanner Interceptor

Built-in interceptor for scanning result sets.

package com.mysql.cj.jdbc.interceptors;

public class ResultSetScannerInterceptor implements QueryInterceptor {
    // Scans result sets for specific patterns
    // Configure via properties:
    //   resultSetScannerRegex - regex pattern to match
    
    public QueryInterceptor init(MysqlConnection conn, Properties props, Log log);
    public <T extends Resultset> T preProcess(Supplier<String> sql, Query interceptedQuery);
    public boolean executeTopLevelOnly();
    public void destroy();
    public <T extends Resultset> T postProcess(Supplier<String> sql, Query interceptedQuery,
                                              T originalResultSet, ServerSession serverSession);
}

Usage:

// Scan result sets for sensitive data patterns
String url = "jdbc:mysql://localhost:3306/mydb" +
             "?queryInterceptors=com.mysql.cj.jdbc.interceptors.ResultSetScannerInterceptor" +
             "&resultSetScannerRegex=\\d{3}-\\d{2}-\\d{4}";  // SSN pattern
Connection conn = DriverManager.getConnection(url, "user", "pass");

// Will scan all result sets and log matches

Server Status Diff Interceptor

Built-in interceptor for tracking server status changes.

package com.mysql.cj.jdbc.interceptors;

public class ServerStatusDiffInterceptor implements QueryInterceptor {
    // Tracks changes in server status variables before/after queries
    
    public QueryInterceptor init(MysqlConnection conn, Properties props, Log log);
    public <T extends Resultset> T preProcess(Supplier<String> sql, Query interceptedQuery);
    public boolean executeTopLevelOnly();
    public void destroy();
    public <T extends Resultset> T postProcess(Supplier<String> sql, Query interceptedQuery,
                                              T originalResultSet, ServerSession serverSession);
}

Usage:

// Track server status changes
String url = "jdbc:mysql://localhost:3306/mydb" +
             "?queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor";
Connection conn = DriverManager.getConnection(url, "user", "pass");

// Will log changes in server status variables

Session Association Interceptor

Built-in interceptor for associating sessions with application context.

package com.mysql.cj.jdbc.interceptors;

public class SessionAssociationInterceptor implements ConnectionLifecycleInterceptor {
    // Associates session with application context
    
    public ConnectionLifecycleInterceptor init(MysqlConnection conn, Properties props, Log log);
    public void destroy();
    public void createNewSession();
    public void transactionBegun();
    public void transactionCompleted();
}

Multiple Interceptors

You can configure multiple interceptors by separating them with commas.

Usage:

// Configure multiple query interceptors
String url = "jdbc:mysql://localhost:3306/mydb" +
             "?queryInterceptors=" +
             "com.mycompany.LoggingInterceptor," +
             "com.mycompany.MetricsInterceptor," +
             "com.mycompany.SecurityInterceptor";

// Configure multiple connection lifecycle interceptors
String url2 = "jdbc:mysql://localhost:3306/mydb" +
              "?connectionLifecycleInterceptors=" +
              "com.mycompany.PoolingInterceptor," +
              "com.mycompany.AuditInterceptor";

Connection conn = DriverManager.getConnection(url, "user", "pass");

Advanced Query Interceptor Example

Complete example showing advanced query interception:

public class MetricsQueryInterceptor implements QueryInterceptor {
    private Log log;
    private Map<String, Long> queryTimes = new ConcurrentHashMap<>();
    private Map<String, AtomicLong> queryCount = new ConcurrentHashMap<>();

    public QueryInterceptor init(MysqlConnection conn, Properties props, Log log) {
        this.log = log;
        return this;
    }

    public <T extends Resultset> T preProcess(Supplier<String> sql, Query interceptedQuery) {
        String query = sql.get();
        queryTimes.put(query, System.currentTimeMillis());
        queryCount.computeIfAbsent(query, k -> new AtomicLong()).incrementAndGet();
        return null;
    }

    public boolean executeTopLevelOnly() {
        return true;
    }

    public void destroy() {
        // Log metrics summary
        log.logInfo("Query Metrics Summary:");
        for (Map.Entry<String, AtomicLong> entry : queryCount.entrySet()) {
            log.logInfo(entry.getKey() + ": executed " + entry.getValue() + " times");
        }
    }

    public <T extends Resultset> T postProcess(Supplier<String> sql, Query interceptedQuery,
                                              T originalResultSet, ServerSession serverSession) {
        String query = sql.get();
        Long startTime = queryTimes.remove(query);
        if (startTime != null) {
            long duration = System.currentTimeMillis() - startTime;
            if (duration > 1000) {
                log.logWarn("Slow query (" + duration + "ms): " + query);
            }
        }
        return originalResultSet;
    }
}

Parameter Bindings Access

Query interceptors can access parameter bindings:

public class ParameterLoggingInterceptor implements QueryInterceptor {
    private Log log;

    public QueryInterceptor init(MysqlConnection conn, Properties props, Log log) {
        this.log = log;
        return this;
    }

    public <T extends Resultset> T preProcess(Supplier<String> sql, Query interceptedQuery) {
        if (interceptedQuery instanceof PreparedQuery) {
            PreparedQuery<?> pq = (PreparedQuery<?>) interceptedQuery;
            ParameterBindings bindings = pq.getParameterBindings();
            
            StringBuilder sb = new StringBuilder("Query: ");
            sb.append(sql.get());
            sb.append("\nParameters: ");
            sb.append(bindings.toString(true));
            
            log.logDebug(sb.toString());
        }
        return null;
    }

    public boolean executeTopLevelOnly() {
        return false;
    }

    public void destroy() {}

    public <T extends Resultset> T postProcess(Supplier<String> sql, Query interceptedQuery,
                                              T originalResultSet, ServerSession serverSession) {
        return originalResultSet;
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-com-mysql--mysql-connector-j

docs

authentication.md

configuration.md

exceptions.md

index.md

interceptors.md

jdbc-advanced.md

jdbc-core.md

jdbc-high-availability.md

logging-monitoring.md

type-system.md

utilities.md

xdevapi-core.md

xdevapi-crud.md

xdevapi-sql.md

tile.json