JDBC Type 4 driver for MySQL with X DevAPI support for document store operations
Direct SQL execution and result handling within the X DevAPI context. These interfaces allow executing SQL statements and processing results while using the X DevAPI session.
Execute SQL statements within X DevAPI sessions.
package com.mysql.cj.xdevapi;
public interface SqlStatement extends Statement<SqlStatement, SqlResult> {
// Parameter binding
SqlStatement bind(Object... values);
SqlStatement bind(List<Object> values);
SqlStatement bind(Map<String, Object> values);
// Execution
SqlResult execute();
}
public class SqlStatementImpl implements SqlStatement {
public SqlStatementImpl(Session session, String sql);
public SqlStatement bind(Object... values);
public SqlStatement bind(List<Object> values);
public SqlStatement bind(Map<String, Object> values);
public SqlResult execute();
}Usage:
Session session = factory.getSession("mysqlx://root:password@localhost:33060/mydb");
// Execute simple SQL
SqlResult result = session.sql("SELECT * FROM users").execute();
// Execute SQL with positional parameters
SqlResult result2 = session.sql("SELECT * FROM users WHERE age > ?")
.bind(25)
.execute();
// Execute SQL with named parameters
SqlResult result3 = session.sql("SELECT * FROM users WHERE age > :minAge AND city = :city")
.bind(Map.of("minAge", 25, "city", "New York"))
.execute();
// Execute DML
SqlResult insertResult = session.sql("INSERT INTO users (name, age) VALUES (?, ?)")
.bind("Alice", 30)
.execute();
System.out.println("Affected rows: " + insertResult.getAffectedItemsCount());
// Execute DDL
session.sql("CREATE TABLE temp (id INT, name VARCHAR(50))").execute();
session.sql("DROP TABLE temp").execute();Handle results from SQL statement execution.
package com.mysql.cj.xdevapi;
public interface SqlResult extends Result, RowResult, Iterator<Row> {
// Check if result has data
boolean hasData();
// Move to next result set
SqlResult nextResult();
// Get auto-increment value
long getAutoIncrementValue();
// Result information
long getAffectedItemsCount();
int getWarningsCount();
Iterator<Warning> getWarnings();
// Row iteration (from RowResult)
boolean hasNext();
Row next();
Row fetchOne();
List<Row> fetchAll();
int count();
// Column metadata (from RowResult)
int getColumnCount();
List<Column> getColumns();
List<String> getColumnNames();
}
public class SqlSingleResult implements SqlResult {
// Single result set implementation
public boolean hasData();
public SqlResult nextResult();
public long getAutoIncrementValue();
public long getAffectedItemsCount();
public int getWarningsCount();
public Iterator<Warning> getWarnings();
public boolean hasNext();
public Row next();
public Row fetchOne();
public List<Row> fetchAll();
public int count();
public int getColumnCount();
public List<Column> getColumns();
public List<String> getColumnNames();
}
public class SqlMultiResult implements SqlResult {
// Multiple result sets implementation
public boolean hasData();
public SqlResult nextResult();
public long getAutoIncrementValue();
public long getAffectedItemsCount();
public int getWarningsCount();
public Iterator<Warning> getWarnings();
public boolean hasNext();
public Row next();
public Row fetchOne();
public List<Row> fetchAll();
public int count();
public int getColumnCount();
public List<Column> getColumns();
public List<String> getColumnNames();
}
public class SqlUpdateResult implements SqlResult {
// DML/DDL result implementation (no data rows)
public boolean hasData();
public SqlResult nextResult();
public long getAutoIncrementValue();
public long getAffectedItemsCount();
public int getWarningsCount();
public Iterator<Warning> getWarnings();
}Usage:
Session session = factory.getSession("mysqlx://root:password@localhost:33060/mydb");
// Query with result set
SqlResult result = session.sql("SELECT * FROM users WHERE age > ?")
.bind(25)
.execute();
if (result.hasData()) {
while (result.hasNext()) {
Row row = result.next();
System.out.println(row.getString("name") + " - " + row.getInt("age"));
}
}
// Get column metadata
List<Column> columns = result.getColumns();
for (Column col : columns) {
System.out.println(col.getColumnName() + " (" + col.getType() + ")");
}
// INSERT with auto-increment
SqlResult insertResult = session.sql("INSERT INTO users (name, age) VALUES (?, ?)")
.bind("Bob", 28)
.execute();
System.out.println("Auto-increment ID: " + insertResult.getAutoIncrementValue());
System.out.println("Affected rows: " + insertResult.getAffectedItemsCount());
// Multiple result sets (from stored procedure)
SqlResult multiResult = session.sql("CALL get_user_stats()").execute();
do {
if (multiResult.hasData()) {
System.out.println("Result set:");
while (multiResult.hasNext()) {
Row row = multiResult.next();
// Process row
}
}
} while ((multiResult = multiResult.nextResult()) != null);
// Check warnings
if (result.getWarningsCount() > 0) {
Iterator<Warning> warnings = result.getWarnings();
while (warnings.hasNext()) {
Warning warning = warnings.next();
System.out.println("Warning: " + warning.getMessage());
}
}
// Fetch all rows at once
List<Row> allRows = result.fetchAll();Internal result builders for constructing result objects.
package com.mysql.cj.xdevapi;
public class SqlResultBuilder implements com.mysql.cj.protocol.ResultBuilder<SqlResult> {
// Build SQL result from protocol messages
public SqlResultBuilder(Session session);
public boolean addProtocolEntity(com.mysql.cj.protocol.ProtocolEntity entity);
public SqlResult build();
}
public class StreamingSqlResultBuilder implements com.mysql.cj.protocol.ResultBuilder<SqlResult> {
// Build streaming SQL result
public StreamingSqlResultBuilder(Session session);
public boolean addProtocolEntity(com.mysql.cj.protocol.ProtocolEntity entity);
public SqlResult build();
}SQL statements respect session transaction boundaries.
Usage:
Session session = factory.getSession("mysqlx://root:password@localhost:33060/mydb");
// Begin transaction
session.startTransaction();
try {
// Execute multiple SQL statements
session.sql("INSERT INTO accounts (name, balance) VALUES (?, ?)")
.bind("Alice", 1000)
.execute();
session.sql("UPDATE accounts SET balance = balance - ? WHERE name = ?")
.bind(100, "Alice")
.execute();
session.sql("INSERT INTO transactions (account, amount) VALUES (?, ?)")
.bind("Alice", -100)
.execute();
// Commit transaction
session.commit();
} catch (Exception e) {
// Rollback on error
session.rollback();
throw e;
}
session.close();Execute SQL on collections (treated as tables).
Usage:
Session session = factory.getSession("mysqlx://root:password@localhost:33060/mydb");
// Query collection as table
SqlResult result = session.sql(
"SELECT doc->>'$.name' as name, doc->>'$.age' as age " +
"FROM mydb.users " +
"WHERE doc->>'$.age' > ?"
).bind(25).execute();
while (result.hasNext()) {
Row row = result.next();
System.out.println(row.getString("name") + " - " + row.getString("age"));
}
// Update collection document via SQL
session.sql(
"UPDATE mydb.users " +
"SET doc = JSON_SET(doc, '$.status', 'active') " +
"WHERE doc->>'$.age' > ?"
).bind(18).execute();
session.close();Install with Tessl CLI
npx tessl i tessl/maven-com-mysql--mysql-connector-j