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

jdbc-advanced.mddocs/

JDBC Advanced Features

Advanced JDBC capabilities including connection pooling, distributed transactions (XA), batch operations, and server-side prepared statements. These features enable high-performance and enterprise-grade database applications.

Capabilities

Connection Pooling

Connection pooling support through PooledConnection and ConnectionPoolDataSource.

package com.mysql.cj.jdbc;

public class MysqlConnectionPoolDataSource extends MysqlDataSource
    implements javax.sql.ConnectionPoolDataSource {

    // Pooled connection creation
    public PooledConnection getPooledConnection() throws SQLException;
    public PooledConnection getPooledConnection(String user, String password) throws SQLException;
}

public class MysqlPooledConnection implements javax.sql.PooledConnection {
    // Constructor
    public MysqlPooledConnection(JdbcConnection connection);

    // Get logical connection
    public Connection getConnection() throws SQLException;

    // Close physical connection
    public void close() throws SQLException;

    // Event listeners
    public void addConnectionEventListener(ConnectionEventListener listener);
    public void removeConnectionEventListener(ConnectionEventListener listener);

    // Statement event listeners
    public void addStatementEventListener(StatementEventListener listener);
    public void removeStatementEventListener(StatementEventListener listener);
}

Usage:

// Create connection pool data source
MysqlConnectionPoolDataSource cpds = new MysqlConnectionPoolDataSource();
cpds.setURL("jdbc:mysql://localhost:3306/mydb");
cpds.setUser("root");
cpds.setPassword("password");

// Get pooled connection
PooledConnection pooledConn = cpds.getPooledConnection();

// Add connection event listener
pooledConn.addConnectionEventListener(new ConnectionEventListener() {
    public void connectionClosed(ConnectionEvent event) {
        System.out.println("Connection closed");
    }

    public void connectionErrorOccurred(ConnectionEvent event) {
        System.out.println("Connection error: " + event.getSQLException());
    }
});

// Get logical connection from pool
Connection conn = pooledConn.getConnection();
// Use connection...
conn.close(); // Returns to pool

// Close physical connection
pooledConn.close();

XA Distributed Transactions

Support for distributed transactions using the XA protocol.

package com.mysql.cj.jdbc;

public class MysqlXADataSource extends MysqlConnectionPoolDataSource
    implements javax.sql.XADataSource {

    // XA connection creation
    public XAConnection getXAConnection() throws SQLException;
    public XAConnection getXAConnection(String user, String password) throws SQLException;
}

public class MysqlXAConnection extends MysqlPooledConnection implements javax.sql.XAConnection {
    // Constructor
    public MysqlXAConnection(JdbcConnection connection, boolean logXaCommands);

    // Get XA resource
    public XAResource getXAResource() throws SQLException;
}

public class SuspendableXAConnection extends MysqlXAConnection {
    // Constructor
    public SuspendableXAConnection(JdbcConnection connection);

    // XA resource with suspend/resume support
    public XAResource getXAResource() throws SQLException;
}

public class MysqlXid implements javax.transaction.xa.Xid {
    // Constructor
    public MysqlXid(byte[] globalTransactionId, byte[] branchQualifier, int formatId);

    // Xid components
    public byte[] getGlobalTransactionId();
    public byte[] getBranchQualifier();
    public int getFormatId();
}

Usage:

// Create XA data source
MysqlXADataSource xads = new MysqlXADataSource();
xads.setURL("jdbc:mysql://localhost:3306/mydb");
xads.setUser("root");
xads.setPassword("password");

// Get XA connection
XAConnection xaConn = xads.getXAConnection();
XAResource xaRes = xaConn.getXAResource();

// Create XID for transaction
Xid xid = new MysqlXid(
    "global-tx-1".getBytes(),
    "branch-1".getBytes(),
    1
);

try {
    // Start XA transaction
    xaRes.start(xid, XAResource.TMNOFLAGS);

    // Get connection and perform work
    Connection conn = xaConn.getConnection();
    Statement stmt = conn.createStatement();
    stmt.executeUpdate("INSERT INTO accounts (name, balance) VALUES ('Alice', 1000)");
    stmt.close();

    // End XA transaction
    xaRes.end(xid, XAResource.TMSUCCESS);

    // Prepare phase
    int prepareResult = xaRes.prepare(xid);

    if (prepareResult == XAResource.XA_OK) {
        // Commit phase
        xaRes.commit(xid, false);
        System.out.println("Transaction committed");
    }
} catch (XAException e) {
    // Rollback on error
    try {
        xaRes.rollback(xid);
    } catch (XAException rollbackEx) {
        rollbackEx.printStackTrace();
    }
    e.printStackTrace();
} finally {
    xaConn.close();
}

Batch Operations

Efficient batch execution of multiple SQL statements.

// Batch operations are part of Statement interfaces

// Statement batch operations
public interface Statement {
    void addBatch(String sql) throws SQLException;
    void clearBatch() throws SQLException;
    int[] executeBatch() throws SQLException;
    long[] executeLargeBatch() throws SQLException;
}

// PreparedStatement batch operations
public interface PreparedStatement extends Statement {
    void addBatch() throws SQLException;
    // Inherits executeBatch() and clearBatch() from Statement
}

Usage:

// Statement batch
Statement stmt = conn.createStatement();
stmt.addBatch("INSERT INTO users (name, age) VALUES ('Alice', 25)");
stmt.addBatch("INSERT INTO users (name, age) VALUES ('Bob', 30)");
stmt.addBatch("INSERT INTO users (name, age) VALUES ('Charlie', 35)");

int[] updateCounts = stmt.executeBatch();
System.out.println("Batch executed: " + updateCounts.length + " statements");

// PreparedStatement batch
String sql = "INSERT INTO users (name, age) VALUES (?, ?)";
PreparedStatement pstmt = conn.prepareStatement(sql);

pstmt.setString(1, "David");
pstmt.setInt(2, 28);
pstmt.addBatch();

pstmt.setString(1, "Eve");
pstmt.setInt(2, 32);
pstmt.addBatch();

pstmt.setString(1, "Frank");
pstmt.setInt(2, 27);
pstmt.addBatch();

int[] batchResults = pstmt.executeBatch();
System.out.println("Inserted " + batchResults.length + " rows");

// Enable rewriteBatchedStatements for better performance
// Set in connection URL: ?rewriteBatchedStatements=true

Server-Side Prepared Statements

Server-side prepared statements for enhanced performance with repeated executions.

package com.mysql.cj.jdbc;

public class ServerPreparedStatement extends ClientPreparedStatement {
    // Server-side prepared statement implementation
    // Inherits all PreparedStatement methods but executes on server

    // Additional server-side specific behavior
    // - Statement is compiled once on server
    // - Parameters sent separately for each execution
    // - Better performance for repeated executions
    // - Uses binary protocol
}

// Connection methods for explicit server-side preparation
public interface JdbcConnection extends Connection {
    PreparedStatement serverPrepareStatement(String sql) throws SQLException;
    PreparedStatement serverPrepareStatement(String sql, int autoGeneratedKeys) throws SQLException;
    PreparedStatement serverPrepareStatement(String sql, int resultSetType, int resultSetConcurrency)
        throws SQLException;
    PreparedStatement serverPrepareStatement(String sql, int resultSetType, int resultSetConcurrency,
                                           int resultSetHoldability) throws SQLException;
    PreparedStatement serverPrepareStatement(String sql, int[] autoGeneratedKeyIndexes)
        throws SQLException;
    PreparedStatement serverPrepareStatement(String sql, String[] autoGeneratedKeyColNames)
        throws SQLException;
}

Usage:

// Enable server-side prepared statements via connection property
String url = "jdbc:mysql://localhost:3306/mydb?useServerPrepStmts=true";
Connection conn = DriverManager.getConnection(url, "root", "password");

// Or explicitly create server-side prepared statement
JdbcConnection mysqlConn = conn.unwrap(JdbcConnection.class);
PreparedStatement pstmt = mysqlConn.serverPrepareStatement(
    "SELECT * FROM users WHERE age > ?"
);

// Execute multiple times - benefits from server-side caching
for (int age = 18; age <= 50; age += 10) {
    pstmt.setInt(1, age);
    ResultSet rs = pstmt.executeQuery();
    // Process results...
    rs.close();
}

pstmt.close();

// Configure prepared statement cache
// Set in URL: ?cachePrepStmts=true&prepStmtCacheSize=250&prepStmtCacheSqlLimit=2048

Statement Wrappers

Wrapper classes for pooled connection statement management.

package com.mysql.cj.jdbc;

public class StatementWrapper implements Statement {
    // Wraps statements for pooled connections
    // Delegates all calls to underlying statement
    // Tracks lifecycle for proper cleanup

    protected Statement wrappedStmt;
    protected ConnectionWrapper connectionWrapper;

    public StatementWrapper(ConnectionWrapper c, MysqlPooledConnection conn, Statement toWrap);

    // All Statement methods delegated to wrappedStmt
    // Close notifications sent to connection wrapper
}

public class PreparedStatementWrapper extends StatementWrapper implements PreparedStatement {
    // Wraps prepared statements for pooled connections

    protected PreparedStatement wrappedPrepStmt;

    public PreparedStatementWrapper(ConnectionWrapper c, MysqlPooledConnection conn,
                                   PreparedStatement toWrap);

    // All PreparedStatement methods delegated to wrappedPrepStmt
}

public class CallableStatementWrapper extends PreparedStatementWrapper
    implements CallableStatement {
    // Wraps callable statements for pooled connections

    protected CallableStatement wrappedCallableStmt;

    public CallableStatementWrapper(ConnectionWrapper c, MysqlPooledConnection conn,
                                   CallableStatement toWrap);

    // All CallableStatement methods delegated to wrappedCallableStmt
}

public class ConnectionWrapper implements JdbcConnection {
    // Wraps connections for pooled connection management

    protected JdbcConnection wrappedConnection;
    protected MysqlPooledConnection pooledConnection;

    public ConnectionWrapper(MysqlPooledConnection pooledConnection, JdbcConnection connection);

    // All Connection methods delegated to wrappedConnection
    // Statement creation returns wrapped statements
    // Close notifications sent to pooled connection
}

Abandoned Connection Cleanup

Automatic cleanup of connections that are not properly closed.

package com.mysql.cj.jdbc;

public class AbandonedConnectionCleanupThread extends Thread {
    // Singleton thread for cleaning up abandoned connections

    // Check if cleanup thread is running
    public static boolean isAlive();

    // Manually trigger cleanup (normally automatic)
    public static void checkedShutdown();

    // Shutdown cleanup thread
    public static void uncheckedShutdown();
}

Usage:

// The cleanup thread is automatically started when needed
// and runs in the background

// To explicitly shutdown (e.g., in web application context listener):
public class MyContextListener implements ServletContextListener {
    public void contextDestroyed(ServletContextEvent event) {
        try {
            AbandonedConnectionCleanupThread.checkedShutdown();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Result Set Factory

Factory for creating different types of result sets.

package com.mysql.cj.jdbc.result;

public class ResultSetFactory {
    // Create result set from result data
    public static ResultSet createFromResultsetRows(
        int resultSetType,
        int resultSetConcurrency,
        ResultsetRows rows,
        JdbcConnection conn,
        StatementImpl stmt
    ) throws SQLException;

    // Result set type constants (from java.sql.ResultSet)
    // TYPE_FORWARD_ONLY - cursor can only move forward
    // TYPE_SCROLL_INSENSITIVE - scrollable, not sensitive to changes
    // TYPE_SCROLL_SENSITIVE - scrollable, sensitive to changes

    // Result set concurrency constants
    // CONCUR_READ_ONLY - read-only result set
    // CONCUR_UPDATABLE - updatable result set
}

Parameter Bindings

Interface to allow PreparedStatement implementations to expose their parameter bindings to QueryInterceptors.

package com.mysql.cj.jdbc;

import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URL;
import java.sql.Array;
import java.sql.Clob;
import java.sql.Date;
import java.sql.Ref;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;

/**
 * Interface to allow PreparedStatement implementations to expose their parameter bindings to QueryInterceptors.
 */
public interface ParameterBindings {
    Array getArray(int parameterIndex) throws SQLException;
    InputStream getAsciiStream(int parameterIndex) throws SQLException;
    BigDecimal getBigDecimal(int parameterIndex) throws SQLException;
    InputStream getBinaryStream(int parameterIndex) throws SQLException;
    java.sql.Blob getBlob(int parameterIndex) throws SQLException;
    boolean getBoolean(int parameterIndex) throws SQLException;
    byte getByte(int parameterIndex) throws SQLException;
    byte[] getBytes(int parameterIndex) throws SQLException;
    Reader getCharacterStream(int parameterIndex) throws SQLException;
    Clob getClob(int parameterIndex) throws SQLException;
    Date getDate(int parameterIndex) throws SQLException;
    double getDouble(int parameterIndex) throws SQLException;
    float getFloat(int parameterIndex) throws SQLException;
    int getInt(int parameterIndex) throws SQLException;
    BigInteger getBigInteger(int parameterIndex) throws SQLException;
    long getLong(int parameterIndex) throws SQLException;
    Reader getNCharacterStream(int parameterIndex) throws SQLException;
    Reader getNClob(int parameterIndex) throws SQLException;
    Object getObject(int parameterIndex) throws SQLException;
    Ref getRef(int parameterIndex) throws SQLException;
    short getShort(int parameterIndex) throws SQLException;
    String getString(int parameterIndex) throws SQLException;
    Time getTime(int parameterIndex) throws SQLException;
    Timestamp getTimestamp(int parameterIndex) throws SQLException;
    URL getURL(int parameterIndex) throws SQLException;
    boolean isNull(int parameterIndex) throws SQLException;
}

Streaming Results

Support for streaming large result sets without loading all data into memory.

package com.mysql.cj.jdbc;

public interface JdbcStatement extends Statement {
    // Enable streaming results (one row at a time)
    void enableStreamingResults() throws SQLException;

    // Disable streaming results (default behavior)
    void disableStreamingResults() throws SQLException;
}

Usage:

// Method 1: Use Statement.setFetchSize(Integer.MIN_VALUE)
Statement stmt = conn.createStatement(
    ResultSet.TYPE_FORWARD_ONLY,
    ResultSet.CONCUR_READ_ONLY
);
stmt.setFetchSize(Integer.MIN_VALUE);

ResultSet rs = stmt.executeQuery("SELECT * FROM large_table");
while (rs.next()) {
    // Process one row at a time
    // Memory usage remains constant
}

// Method 2: Use enableStreamingResults()
JdbcStatement mysqlStmt = stmt.unwrap(JdbcStatement.class);
mysqlStmt.enableStreamingResults();

ResultSet rs2 = mysqlStmt.executeQuery("SELECT * FROM another_large_table");
while (rs2.next()) {
    // Process streaming results
}

// Important: Only one streaming result set can be open per connection
// Close result set before executing another query
rs.close();
stmt.close();

Large Update Counts

Support for update counts exceeding Integer.MAX_VALUE.

package com.mysql.cj.jdbc;

public interface JdbcStatement extends Statement {
    // Execute with large update count
    long executeLargeUpdate(String sql) throws SQLException;
    long executeLargeUpdate(String sql, int autoGeneratedKeys) throws SQLException;
    long executeLargeUpdate(String sql, int[] columnIndexes) throws SQLException;
    long executeLargeUpdate(String sql, String[] columnNames) throws SQLException;

    // Get large update count
    long getLargeUpdateCount() throws SQLException;

    // Large batch execution
    long[] executeLargeBatch() throws SQLException;

    // Large max rows
    void setLargeMaxRows(long max) throws SQLException;
    long getLargeMaxRows() throws SQLException;
}

public interface JdbcPreparedStatement extends PreparedStatement {
    // Execute with large update count
    long executeLargeUpdate() throws SQLException;
}

Usage:

Statement stmt = conn.createStatement();

// Execute update returning large count
long rowsAffected = stmt.executeLargeUpdate(
    "DELETE FROM logs WHERE timestamp < '2020-01-01'"
);
System.out.println("Deleted " + rowsAffected + " rows");

// Large batch execution
stmt.addBatch("UPDATE table1 SET col = 'value'");
stmt.addBatch("UPDATE table2 SET col = 'value'");
long[] largeCounts = stmt.executeLargeBatch();

// Set large max rows
stmt.setLargeMaxRows(10_000_000_000L);
long maxRows = stmt.getLargeMaxRows();

Local Infile

Support for LOAD DATA LOCAL INFILE operations.

package com.mysql.cj.jdbc;

public interface JdbcStatement extends Statement {
    // Set input stream for LOCAL INFILE
    void setLocalInfileInputStream(InputStream stream);

    // Get input stream for LOCAL INFILE
    InputStream getLocalInfileInputStream();
}

Usage:

// Enable LOCAL INFILE in connection
String url = "jdbc:mysql://localhost:3306/mydb?allowLoadLocalInfile=true";
Connection conn = DriverManager.getConnection(url, "root", "password");

Statement stmt = conn.createStatement();
JdbcStatement mysqlStmt = stmt.unwrap(JdbcStatement.class);

// Provide input stream for LOAD DATA LOCAL INFILE
InputStream fileInput = new FileInputStream("data.csv");
mysqlStmt.setLocalInfileInputStream(fileInput);

// Execute LOAD DATA LOCAL INFILE
stmt.execute(
    "LOAD DATA LOCAL INFILE 'data.csv' INTO TABLE mytable " +
    "FIELDS TERMINATED BY ',' " +
    "LINES TERMINATED BY '\\n'"
);

fileInput.close();
stmt.close();

JDBC Property Set

Configuration properties specific to JDBC implementation.

package com.mysql.cj.jdbc;

public interface JdbcPropertySet extends com.mysql.cj.conf.PropertySet {
    // Expose all connection properties as DriverPropertyInfo
    DriverPropertyInfo[] exposeAsProperties(Properties info) throws SQLException;
}

public class JdbcPropertySetImpl implements JdbcPropertySet {
    // Implementation of JDBC property set

    public JdbcPropertySetImpl();

    public void initializeProperties(Properties props);

    public DriverPropertyInfo[] exposeAsProperties(Properties info) throws SQLException;
}

Mini Admin Utilities

Utility functions for administrative operations.

package com.mysql.cj.jdbc.admin;

public class MiniAdmin {
    // Constructor
    public MiniAdmin(String jdbcUrl) throws SQLException;
    public MiniAdmin(String jdbcUrl, Properties props) throws SQLException;

    // Shutdown MySQL server
    public void shutdown() throws SQLException;
}

Usage:

// Create admin instance
MiniAdmin admin = new MiniAdmin("jdbc:mysql://localhost:3306/");

// Shutdown MySQL server
admin.shutdown();

C3P0 Integration

Connection tester for C3P0 connection pool integration.

package com.mysql.cj.jdbc.integration.c3p0;

public class MysqlConnectionTester implements com.mchange.v2.c3p0.ConnectionTester {
    // Test connection liveness using COM_PING
    public int activeCheckConnection(Connection c);

    // Test connection on checkout
    public int statusOnException(Connection c, Throwable t);
}

Usage with C3P0:

// Configure C3P0 data source with MySQL connection tester
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass("com.mysql.cj.jdbc.Driver");
cpds.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
cpds.setUser("root");
cpds.setPassword("password");

// Use MySQL-specific connection tester
cpds.setConnectionTesterClassName(
    "com.mysql.cj.jdbc.integration.c3p0.MysqlConnectionTester"
);

// Pool configuration
cpds.setMinPoolSize(5);
cpds.setMaxPoolSize(20);
cpds.setAcquireIncrement(5);
cpds.setTestConnectionOnCheckout(true);

Connection conn = cpds.getConnection();

Iterator Block

Helper for iterating over result sets.

package com.mysql.cj.jdbc;

public abstract class IterateBlock<T> {
    // Constructor
    public IterateBlock();

    // Override this method to process each row
    public abstract void forEach(T each) throws SQLException;

    // Execute iteration
    public final void doForAll(Iterator<T> iterator) throws SQLException;
}

Usage:

// Custom iteration logic
IterateBlock<Row> rowProcessor = new IterateBlock<Row>() {
    @Override
    public void forEach(Row row) throws SQLException {
        // Process each row
        System.out.println("Processing row: " + row);
    }
};

// Execute iteration
// rowProcessor.doForAll(rowIterator);

Close Options

Enumeration for connection close options.

package com.mysql.cj.jdbc;

public enum CloseOption {
    IMPLICIT,  // Close operation initiated internally by a clean up routine
    FORCED,    // A forced, hard close
    ROLLBACK,  // Allow rollback during the close operation
    PROPAGATE, // Allow propagating the close operation to dependents and owner objects
    NO_CACHE;  // Does not allow caching the closing object

    public boolean in(CloseOption... options);
    public boolean notIn(CloseOption... options);
}

Connection Change User

Support for changing the authenticated user on an existing connection.

package com.mysql.cj.jdbc;

public interface JdbcConnection extends Connection {
    // Change authenticated user
    void changeUser(String userName, String newPassword) throws SQLException;
}

Usage:

Connection conn = DriverManager.getConnection(url, "user1", "pass1");

// Change to different user
JdbcConnection mysqlConn = conn.unwrap(JdbcConnection.class);
mysqlConn.changeUser("user2", "pass2");

// Connection now authenticated as user2

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