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

xdevapi-crud.mddocs/

X DevAPI CRUD Operations

Fluent statement builders for Create, Read, Update, and Delete operations on collections and tables. These interfaces provide a chainable API for building complex queries and modifications.

Capabilities

Statement Base Interface

The base interface for all X DevAPI statements, providing common functionality for execution and parameter binding.

package com.mysql.cj.xdevapi;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

public interface Statement<STMT_T, RES_T> {
    // Lock contention options
    enum LockContention {
        DEFAULT,      // Wait until the row lock is released
        NOWAIT,       // Do not wait to acquire row lock; fail with error if locked
        SKIP_LOCKED;  // Do not wait; remove locked rows from result set
    }

    // Synchronous execution
    RES_T execute();

    // Asynchronous execution
    CompletableFuture<RES_T> executeAsync();

    // Parameter binding
    // Note: Some bind methods have default implementations that throw UnsupportedOperationException
    // for statements that don't support parameter binding. Check specific statement implementations.
    STMT_T clearBindings();
    STMT_T bind(String argName, Object value);
    STMT_T bind(Map<String, Object> values);
    STMT_T bind(List<Object> values);
    STMT_T bind(Object... values);
}

Usage:

// Asynchronous execution
CompletableFuture<DocResult> futureResult = collection.find("age > :minAge")
    .bind("minAge", 18)
    .executeAsync();

futureResult.thenAccept(result -> {
    while (result.hasNext()) {
        DbDoc doc = result.next();
        System.out.println(doc.toString());
    }
});

// Multiple parameter binding approaches
FindStatement stmt = collection.find("name = :name AND age = :age");

// Bind individually
stmt.bind("name", "Alice").bind("age", 30);

// Bind with map
Map<String, Object> params = new HashMap<>();
params.put("name", "Alice");
params.put("age", 30);
stmt.bind(params).execute();

// Bind with list (positional binding with indices)
stmt.bind(Arrays.asList("Alice", 30)).execute();

// Bind with varargs
stmt.bind("Alice", 30).execute();

Add Statement (Collection)

Statement for adding documents to a collection.

package com.mysql.cj.xdevapi;

public interface AddStatement extends Statement<AddStatement, AddResult> {
    // Add documents
    AddStatement add(String jsonString);
    AddStatement add(DbDoc... docs);
    AddStatement add(String... jsonStrings);
    AddStatement add(Map<String, ?> docMap);

    // Upsert support (used internally by Collection.addOrReplaceOne)
    boolean isUpsert();
    AddStatement setUpsert(boolean upsert);

    // Execute statement
    AddResult execute();
}

public class AddStatementImpl extends FilterableStatement<AddStatement, AddResult>
    implements AddStatement {
    // Implementation

    public AddStatement add(DbDoc... docs);
    public AddStatement add(String... jsonStrings);
    public AddStatement add(Map<String, ?> docMap);
    public AddResult execute();
}

public interface AddResult extends Result {
    // Get generated document IDs
    List<String> getGeneratedIds();

    // Get affected items count
    long getAffectedItemsCount();

    // Get warnings
    int getWarningsCount();
    Iterator<Warning> getWarnings();
}

public class AddResultImpl implements AddResult {
    public List<String> getGeneratedIds();
    public long getAffectedItemsCount();
    public int getWarningsCount();
    public Iterator<Warning> getWarnings();
}

Usage:

Collection users = schema.getCollection("users");

// Add single document
AddResult result = users.add("{\"name\": \"Alice\", \"age\": 30}").execute();
System.out.println("Generated IDs: " + result.getGeneratedIds());

// Add multiple documents
DbDoc doc1 = users.newDoc().add("name", new JsonString().setValue("Bob")).add("age", new JsonNumber().setValue("25"));
DbDoc doc2 = users.newDoc().add("name", new JsonString().setValue("Charlie")).add("age", new JsonNumber().setValue("35"));
AddResult result2 = users.add(doc1, doc2).execute();

// Add from map
Map<String, Object> userMap = new HashMap<>();
userMap.put("name", "David");
userMap.put("age", 28);
users.add(userMap).execute();

Find Statement (Collection)

Statement for finding documents in a collection.

package com.mysql.cj.xdevapi;

public interface FindStatement extends Statement<FindStatement, DocResult> {
    // Projection
    FindStatement fields(String... projection);
    FindStatement fields(Expression projection);

    // Grouping
    FindStatement groupBy(String... fields);
    FindStatement having(String having);

    // Ordering
    FindStatement orderBy(String... sortFields);
    FindStatement sort(String... sortFields);

    // Limiting
    FindStatement limit(long numberOfRows);
    FindStatement offset(long numberOfRows);

    /**
     * @deprecated Deprecated in Connector/J 8.0.12, use {@link #offset(long)} instead.
     */
    @Deprecated
    default FindStatement skip(long limitOffset) {
        return offset(limitOffset);
    }

    // Locking
    FindStatement lockShared();
    FindStatement lockShared(Statement.LockContention lockContention);
    FindStatement lockExclusive();
    FindStatement lockExclusive(Statement.LockContention lockContention);

    // Binding
    FindStatement bind(String name, Object value);
    FindStatement bind(Map<String, Object> values);

    // Execution
    DocResult execute();
}

public class FindStatementImpl extends FilterableStatement<FindStatement, DocResult>
    implements FindStatement {
    public FindStatement fields(String... projection);
    public FindStatement fields(Expression projection);
    public FindStatement groupBy(String... fields);
    public FindStatement having(String having);
    public FindStatement orderBy(String... sortFields);
    public FindStatement sort(String... sortFields);
    public FindStatement limit(long numberOfRows);
    public FindStatement offset(long numberOfRows);
    public FindStatement lockShared();
    public FindStatement lockShared(Statement.LockContention lockContention);
    public FindStatement lockExclusive();
    public FindStatement lockExclusive(Statement.LockContention lockContention);
    public FindStatement bind(String name, Object value);
    public FindStatement bind(Map<String, Object> values);
    public DocResult execute();
}

public interface DocResult extends FetchResult<DbDoc>, Iterator<DbDoc> {
    // Iteration
    boolean hasNext();
    DbDoc next();

    // Fetch operations
    DbDoc fetchOne();
    List<DbDoc> fetchAll();
    int count();

    // Warnings
    int getWarningsCount();
    Iterator<Warning> getWarnings();
}

public class DocResultImpl implements DocResult {
    public boolean hasNext();
    public DbDoc next();
    public DbDoc fetchOne();
    public List<DbDoc> fetchAll();
    public int count();
    public int getWarningsCount();
    public Iterator<Warning> getWarnings();
}

Usage:

Collection users = schema.getCollection("users");

// Simple find
DocResult result = users.find().execute();
while (result.hasNext()) {
    DbDoc doc = result.next();
    System.out.println(doc.toString());
}

// Find with condition
DocResult result2 = users.find("age > :minAge")
    .bind("minAge", 25)
    .execute();

// Find with projection
DocResult result3 = users.find("age > 25")
    .fields("name", "age")
    .execute();

// Find with ordering and limiting
DocResult result4 = users.find()
    .orderBy("age DESC")
    .limit(10)
    .execute();

// Find with grouping
DocResult result5 = users.find()
    .fields("age", "COUNT(*) as count")
    .groupBy("age")
    .having("count > 1")
    .execute();

// Find with locking
session.startTransaction();
DocResult result6 = users.find("_id = :id")
    .bind("id", "someId")
    .lockExclusive()
    .execute();
// Modify locked document
session.commit();

// Fetch all at once
List<DbDoc> allDocs = users.find().execute().fetchAll();

Modify Statement (Collection)

Statement for modifying documents in a collection.

package com.mysql.cj.xdevapi;

public interface ModifyStatement extends Statement<ModifyStatement, Result> {
    // Modification operations
    ModifyStatement set(String docPath, Object value);
    ModifyStatement change(String docPath, Object value);
    ModifyStatement unset(String... fields);
    ModifyStatement arrayInsert(String docPath, Object value);
    ModifyStatement arrayAppend(String docPath, Object value);
    ModifyStatement patch(DbDoc patch);
    ModifyStatement patch(String jsonPatch);

    // Ordering and limiting
    ModifyStatement sort(String... sortFields);
    ModifyStatement limit(long numberOfRows);

    // Binding
    ModifyStatement bind(String name, Object value);
    ModifyStatement bind(Map<String, Object> values);

    // Execution
    Result execute();
}

public class ModifyStatementImpl extends FilterableStatement<ModifyStatement, Result>
    implements ModifyStatement {
    public ModifyStatement set(String docPath, Object value);
    public ModifyStatement change(String docPath, Object value);
    public ModifyStatement unset(String... fields);
    public ModifyStatement arrayInsert(String docPath, Object value);
    public ModifyStatement arrayAppend(String docPath, Object value);
    public ModifyStatement patch(DbDoc patch);
    public ModifyStatement patch(String jsonPatch);
    public ModifyStatement sort(String... sortFields);
    public ModifyStatement limit(long numberOfRows);
    public ModifyStatement bind(String name, Object value);
    public ModifyStatement bind(Map<String, Object> values);
    public Result execute();
}

public enum UpdateType {
    SET,
    ITEM_REMOVE,
    ITEM_SET,
    ITEM_REPLACE,
    ITEM_MERGE,
    ARRAY_INSERT,
    ARRAY_APPEND,
    MERGE_PATCH;
}

public class UpdateSpec {
    public UpdateSpec(UpdateType type, String path);
    public UpdateSpec setValue(Object value);
    public UpdateType getUpdateType();
    public String getSource();
    public Object getValue();
}

Usage:

Collection users = schema.getCollection("users");

// Set field value
users.modify("_id = :id")
    .set("age", 31)
    .bind("id", "someId")
    .execute();

// Unset field
users.modify("_id = :id")
    .unset("middleName")
    .bind("id", "someId")
    .execute();

// Change field value (only if it exists)
users.modify("age > 25")
    .change("status", "active")
    .execute();

// Array operations
users.modify("_id = :id")
    .arrayAppend("hobbies", "reading")
    .bind("id", "someId")
    .execute();

users.modify("_id = :id")
    .arrayInsert("hobbies[0]", "coding")
    .bind("id", "someId")
    .execute();

// Patch document
DbDoc patch = new DbDocImpl();
patch.add("age", new JsonNumber().setValue("32"));
patch.add("city", new JsonString().setValue("New York"));
users.modify("_id = :id")
    .patch(patch)
    .bind("id", "someId")
    .execute();

// Multiple modifications
users.modify("age > :minAge")
    .set("status", "verified")
    .set("lastUpdated", Expression.expr("NOW()"))
    .bind("minAge", 18)
    .limit(100)
    .execute();

// Use expression
users.modify("_id = :id")
    .set("visits", Expression.expr("visits + 1"))
    .bind("id", "someId")
    .execute();

Remove Statement (Collection)

Statement for removing documents from a collection.

package com.mysql.cj.xdevapi;

public interface RemoveStatement extends Statement<RemoveStatement, Result> {
    // Ordering and limiting
    RemoveStatement sort(String... sortFields);
    RemoveStatement limit(long numberOfRows);

    // Binding
    RemoveStatement bind(String name, Object value);
    RemoveStatement bind(Map<String, Object> values);

    // Execution
    Result execute();
}

public class RemoveStatementImpl extends FilterableStatement<RemoveStatement, Result>
    implements RemoveStatement {
    public RemoveStatement sort(String... sortFields);
    public RemoveStatement limit(long numberOfRows);
    public RemoveStatement bind(String name, Object value);
    public RemoveStatement bind(Map<String, Object> values);
    public Result execute();
}

public interface Result {
    long getAffectedItemsCount();
    int getWarningsCount();
    Iterator<Warning> getWarnings();
}

Usage:

Collection users = schema.getCollection("users");

// Remove with condition
Result result = users.remove("age < :minAge")
    .bind("minAge", 18)
    .execute();
System.out.println("Removed: " + result.getAffectedItemsCount());

// Remove with limit
users.remove("status = 'inactive'")
    .limit(10)
    .execute();

// Remove with sorting
users.remove("age > 65")
    .sort("age DESC")
    .limit(5)
    .execute();

// Remove all matching
users.remove("verified = false").execute();

Insert Statement (Table)

Statement for inserting rows into a table.

package com.mysql.cj.xdevapi;

public interface InsertStatement extends Statement<InsertStatement, InsertResult> {
    // Add values
    InsertStatement values(Object... values);
    InsertStatement values(List<Object> values);

    // Execution
    InsertResult execute();
}

public class InsertStatementImpl implements InsertStatement {
    public InsertStatement values(Object... values);
    public InsertStatement values(List<Object> values);
    public InsertResult execute();
}

public interface InsertResult extends Result {
    Long getAutoIncrementValue();
    long getAffectedItemsCount();
    int getWarningsCount();
    Iterator<Warning> getWarnings();
}

public class InsertResultImpl implements InsertResult {
    public Long getAutoIncrementValue();
    public long getAffectedItemsCount();
    public int getWarningsCount();
    public Iterator<Warning> getWarnings();
}

public class InsertParams {
    // Helper class for collecting insert parameters
    public InsertParams(List<String> fields);
    public void addRow(List<Object> row);
    public List<String> getFields();
    public List<List<Object>> getRows();
}

Usage:

Table employees = schema.getTable("employees");

// Insert single row
InsertResult result = employees.insert("name", "age", "department")
    .values("Alice", 30, "Engineering")
    .execute();
System.out.println("Auto-increment ID: " + result.getAutoIncrementValue());

// Insert multiple rows
employees.insert("name", "age", "department")
    .values("Bob", 25, "Sales")
    .values("Charlie", 35, "Marketing")
    .values("David", 28, "Engineering")
    .execute();

// Insert with nulls
employees.insert("name", "age", "department")
    .values("Eve", 32, null)
    .execute();

// Insert from list
List<Object> row = Arrays.asList("Frank", 29, "IT");
employees.insert("name", "age", "department")
    .values(row)
    .execute();

Select Statement (Table)

Statement for selecting rows from a table.

package com.mysql.cj.xdevapi;

public interface SelectStatement extends Statement<SelectStatement, RowResult> {
    // Filtering
    SelectStatement where(String searchCondition);

    // Grouping
    SelectStatement groupBy(String... fields);
    SelectStatement having(String having);

    // Ordering
    SelectStatement orderBy(String... sortFields);

    // Limiting
    SelectStatement limit(long numberOfRows);
    SelectStatement offset(long numberOfRows);

    // Locking
    SelectStatement lockShared();
    SelectStatement lockShared(Statement.LockContention lockContention);
    SelectStatement lockExclusive();
    SelectStatement lockExclusive(Statement.LockContention lockContention);

    // Binding
    SelectStatement bind(String name, Object value);
    SelectStatement bind(Map<String, Object> values);

    // Execution
    RowResult execute();

    // Filter parameters (internal use)
    FilterParams getFilterParams();
}

public class SelectStatementImpl implements SelectStatement {
    public SelectStatement where(String searchCondition);
    public SelectStatement groupBy(String... fields);
    public SelectStatement having(String having);
    public SelectStatement orderBy(String... sortFields);
    public SelectStatement limit(long numberOfRows);
    public SelectStatement offset(long numberOfRows);
    public SelectStatement lockShared();
    public SelectStatement lockShared(Statement.LockContention lockContention);
    public SelectStatement lockExclusive();
    public SelectStatement lockExclusive(Statement.LockContention lockContention);
    public SelectStatement bind(String name, Object value);
    public SelectStatement bind(Map<String, Object> values);
    public RowResult execute();
}

public interface RowResult extends FetchResult<Row>, Iterator<Row> {
    // Iteration
    boolean hasNext();
    Row next();

    // Fetch operations
    Row fetchOne();
    List<Row> fetchAll();
    int count();

    // Metadata
    int getColumnCount();
    List<Column> getColumns();
    List<String> getColumnNames();

    // Warnings
    int getWarningsCount();
    Iterator<Warning> getWarnings();
}

public class RowResultImpl implements RowResult {
    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 int getWarningsCount();
    public Iterator<Warning> getWarnings();
}

Usage:

Table employees = schema.getTable("employees");

// Simple select
RowResult result = employees.select("name", "age", "department").execute();
while (result.hasNext()) {
    Row row = result.next();
    System.out.println(row.getString("name") + " - " + row.getInt("age"));
}

// Select with condition
RowResult result2 = employees.select("*")
    .where("age > :minAge AND department = :dept")
    .bind("minAge", 25)
    .bind("dept", "Engineering")
    .execute();

// Select with ordering and limiting
RowResult result3 = employees.select("name", "salary")
    .where("department = 'Sales'")
    .orderBy("salary DESC")
    .limit(10)
    .execute();

// Select with grouping
RowResult result4 = employees.select("department", "COUNT(*) as count", "AVG(salary) as avg_salary")
    .groupBy("department")
    .having("count > 5")
    .execute();

// Select with offset
RowResult result5 = employees.select("*")
    .orderBy("id")
    .limit(20)
    .offset(40)  // Skip first 40 rows
    .execute();

// Get column metadata
List<Column> columns = result.getColumns();
for (Column col : columns) {
    System.out.println(col.getColumnName() + " - " + col.getType());
}

Update Statement (Table)

Statement for updating rows in a table.

package com.mysql.cj.xdevapi;

public interface UpdateStatement extends Statement<UpdateStatement, Result> {
    // Set field values
    UpdateStatement set(String field, Object value);

    // Filtering
    UpdateStatement where(String searchCondition);

    // Ordering and limiting
    UpdateStatement orderBy(String... sortFields);
    UpdateStatement limit(long numberOfRows);

    // Binding
    UpdateStatement bind(String name, Object value);
    UpdateStatement bind(Map<String, Object> values);

    // Execution
    Result execute();
}

public class UpdateStatementImpl implements UpdateStatement {
    public UpdateStatement set(String field, Object value);
    public UpdateStatement where(String searchCondition);
    public UpdateStatement orderBy(String... sortFields);
    public UpdateStatement limit(long numberOfRows);
    public UpdateStatement bind(String name, Object value);
    public UpdateStatement bind(Map<String, Object> values);
    public Result execute();
}

public class UpdateParams {
    // Helper class for collecting update parameters
    public UpdateParams();
    public void addField(String field, Object value);
    public Map<String, Object> getFields();
}

public class UpdateResult implements Result {
    public long getAffectedItemsCount();
    public int getWarningsCount();
    public Iterator<Warning> getWarnings();
}

Usage:

Table employees = schema.getTable("employees");

// Update with condition
Result result = employees.update()
    .set("salary", 55000)
    .where("name = :name")
    .bind("name", "Alice")
    .execute();
System.out.println("Updated: " + result.getAffectedItemsCount());

// Update multiple fields
employees.update()
    .set("salary", 60000)
    .set("department", "Senior Engineering")
    .where("age > :minAge AND department = :dept")
    .bind("minAge", 30)
    .bind("dept", "Engineering")
    .execute();

// Update with limit
employees.update()
    .set("bonus", 1000)
    .where("performance = 'excellent'")
    .limit(10)
    .execute();

// Update with expression
employees.update()
    .set("salary", Expression.expr("salary * 1.1"))
    .where("department = 'Sales'")
    .execute();

Delete Statement (Table)

Statement for deleting rows from a table.

package com.mysql.cj.xdevapi;

public interface DeleteStatement extends Statement<DeleteStatement, Result> {
    // Filtering
    DeleteStatement where(String searchCondition);

    // Ordering and limiting
    DeleteStatement orderBy(String... sortFields);
    DeleteStatement limit(long numberOfRows);

    // Binding
    DeleteStatement bind(String name, Object value);
    DeleteStatement bind(Map<String, Object> values);

    // Execution
    Result execute();
}

public class DeleteStatementImpl implements DeleteStatement {
    public DeleteStatement where(String searchCondition);
    public DeleteStatement orderBy(String... sortFields);
    public DeleteStatement limit(long numberOfRows);
    public DeleteStatement bind(String name, Object value);
    public DeleteStatement bind(Map<String, Object> values);
    public Result execute();
}

Usage:

Table employees = schema.getTable("employees");

// Delete with condition
Result result = employees.delete()
    .where("age > :maxAge")
    .bind("maxAge", 65)
    .execute();
System.out.println("Deleted: " + result.getAffectedItemsCount());

// Delete with limit
employees.delete()
    .where("status = 'inactive'")
    .limit(10)
    .execute();

// Delete with ordering
employees.delete()
    .where("department = 'Sales'")
    .orderBy("hire_date")
    .limit(5)
    .execute();

// Delete all matching
employees.delete()
    .where("terminated = true")
    .execute();

Base Statement Interfaces

Base interfaces for statement building.

package com.mysql.cj.xdevapi;

public interface Statement<STMT_T, RES_T> {
    // Execute statement
    RES_T execute();
}

public interface FetchResult<T> {
    // Fetch operations
    T fetchOne();
    List<T> fetchAll();
    int count();
}

/**
 * Lock contention options defined as a nested enum in the Statement interface.
 * Use as Statement.LockContention.DEFAULT, Statement.LockContention.NOWAIT, etc.
 */
public static enum Statement.LockContention {
    DEFAULT,    // Wait until the row lock is released
    NOWAIT,     // Fail with error if row is locked
    SKIP_LOCKED // Remove locked rows from result set
}

Filterable Statement

Abstract base class for statements with filtering capabilities.

package com.mysql.cj.xdevapi;

public abstract class FilterableStatement<STMT_T, RES_T> implements Statement<STMT_T, RES_T> {
    // Subclasses implement specific filtering logic
}

public abstract class PreparableStatement<RES_T> {
    // Base class for statements that can be prepared
    // (Future enhancement for prepared statement support)
}

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