JDBC Type 4 driver for MySQL with X DevAPI support for document store operations
Core X DevAPI interfaces for session management, schema access, and basic document/table operations. X DevAPI provides a modern, NoSQL-style API for MySQL document store and relational operations.
Factory for creating X DevAPI sessions.
package com.mysql.cj.xdevapi;
public class SessionFactory {
// Constructor
public SessionFactory();
// Create session from URL string
public Session getSession(String url);
// Create session from properties
public Session getSession(Properties properties);
}Usage:
SessionFactory factory = new SessionFactory();
// Create session from URL
Session session = factory.getSession("mysqlx://root:password@localhost:33060/mydb");
// Create session from properties
Properties props = new Properties();
props.setProperty("host", "localhost");
props.setProperty("port", "33060");
props.setProperty("user", "root");
props.setProperty("password", "password");
props.setProperty("database", "mydb");
Session session2 = factory.getSession(props);
// Use session...
session.close();Factory for creating X DevAPI clients with connection pooling.
package com.mysql.cj.xdevapi;
public class ClientFactory {
// Constructor
public ClientFactory();
// Create client from URL and JSON properties
public Client getClient(String url, String clientPropsJson);
// Create client from URL and properties object
public Client getClient(String url, Properties clientProps);
}Usage:
// Create client with pooling configuration
ClientFactory factory = new ClientFactory();
String url = "mysqlx://root:password@localhost:33060/mydb";
String poolConfig = "{" +
"\"pooling\": {" +
"\"enabled\": true," +
"\"maxSize\": 25," +
"\"maxIdleTime\": 30000," +
"\"queueTimeout\": 5000" +
"}" +
"}";
Client client = factory.getClient(url, poolConfig);
// Get sessions from pool
Session session1 = client.getSession();
Session session2 = client.getSession();
// Use sessions...
session1.close(); // Returns to pool
session2.close(); // Returns to pool
// Close client and all pooled connections
client.close();Client interface for managing pooled sessions.
package com.mysql.cj.xdevapi;
public interface Client extends Closeable {
// Get session from pool
Session getSession();
// Close client and all sessions
void close();
// Client property keys
public enum ClientProperty {
POOLING_ENABLED("pooling.enabled"),
POOLING_MAX_SIZE("pooling.maxSize"),
POOLING_MAX_IDLE_TIME("pooling.maxIdleTime"),
POOLING_QUEUE_TIMEOUT("pooling.queueTimeout");
public String getKeyName();
}
}
public class ClientImpl implements Client {
// Implementation of Client interface
public Session getSession();
public void close();
}Session interface for database operations and transaction management.
package com.mysql.cj.xdevapi;
public interface Session extends Closeable {
// Schema access
Schema getDefaultSchema();
Schema getSchema(String schemaName);
List<Schema> getSchemas();
// Create schema
Schema createSchema(String schemaName);
Schema createSchema(String schemaName, boolean reuseExisting);
// Drop schema
void dropSchema(String schemaName);
// SQL execution
SqlStatement sql(String sql);
// Session state
String getUri();
boolean isOpen();
void close();
// Schema information
String getDefaultSchemaName();
// Transaction management
void startTransaction();
void commit();
void rollback();
void rollbackTo(String name);
// Savepoints
String setSavepoint();
String setSavepoint(String name);
void releaseSavepoint(String name);
}Usage:
Session session = factory.getSession("mysqlx://root:password@localhost:33060/mydb");
// Get default schema
Schema defaultSchema = session.getDefaultSchema();
// Get specific schema
Schema schema = session.getSchema("mydb");
// Create new schema
Schema newSchema = session.createSchema("newdb");
// Drop schema
session.dropSchema("olddb");
// Transaction management
session.startTransaction();
try {
Collection users = schema.getCollection("users");
users.add("{\"name\": \"Alice\", \"age\": 30}").execute();
session.commit();
} catch (Exception e) {
session.rollback();
throw e;
}
// Savepoints
session.startTransaction();
String sp1 = session.setSavepoint("sp1");
// Do some work...
session.rollbackTo(sp1);
session.commit();
session.close();Internal interface for transforming X DevAPI filter parameters into X Protocol message entities.
package com.mysql.cj.xdevapi;
public interface FilterParams {
// Row lock types
public enum RowLock {
SHARED_LOCK(1), // Lock matching rows against updates
EXCLUSIVE_LOCK(2); // Lock matching rows so no other transactions can read or write to it
private int rowLock;
private RowLock(int rowLock);
public int asNumber();
}
// Row lock options
public enum RowLockOptions {
NOWAIT(1), // Do not wait to acquire row lock, fail with an error if a requested row is locked
SKIP_LOCKED(2); // Do not wait to acquire a row lock, remove locked rows from the result set
private int rowLockOption;
private RowLockOptions(int rowLockOption);
public int asNumber();
}
// Collection and order
Object getCollection();
Object getOrder();
void setOrder(String... orderExpression);
// Limit and offset
Long getLimit();
void setLimit(Long limit);
Long getOffset();
void setOffset(Long offset);
boolean supportsOffset();
// Criteria and arguments
Object getCriteria();
void setCriteria(String criteriaString);
Object getArgs();
void addArg(String name, Object value);
void verifyAllArgsBound();
void clearArgs();
// Projection and grouping
boolean isRelational();
void setFields(String... projection);
Object getFields();
void setGrouping(String... groupBy);
Object getGrouping();
void setGroupingCriteria(String having);
Object getGroupingCriteria();
// Locking
RowLock getLock();
void setLock(RowLock rowLock);
RowLockOptions getLockOption();
void setLockOption(RowLockOptions rowLockOption);
}Schema interface for accessing collections and tables.
package com.mysql.cj.xdevapi;
public interface Schema extends DatabaseObject {
// Collection operations
Collection getCollection(String name);
Collection getCollection(String name, boolean requireExists);
Collection createCollection(String name);
Collection createCollection(String name, boolean reuseExisting);
Collection createCollection(String collectionName, CreateCollectionOptions options);
void modifyCollection(String collectionName, ModifyCollectionOptions options);
List<Collection> getCollections();
List<Collection> getCollections(String pattern);
void dropCollection(String collectionName);
// Table operations
Table getTable(String name);
Table getTable(String name, boolean requireExists);
Table getCollectionAsTable(String name);
List<Table> getTables();
List<Table> getTables(String pattern);
// Schema metadata
String getName();
Session getSession();
boolean existsInDatabase();
// Nested classes for collection configuration
public class CreateCollectionOptions {
public CreateCollectionOptions setReuseExisting(boolean reuse);
public Boolean getReuseExisting();
public CreateCollectionOptions setValidation(Validation validation);
public Validation getValidation();
}
public class ModifyCollectionOptions {
public ModifyCollectionOptions setValidation(Validation validation);
public Validation getValidation();
}
public static class Validation {
public static enum ValidationLevel {
STRICT, // Enable JSON schema validation for documents
OFF; // Disable JSON schema validation
}
public Validation setLevel(ValidationLevel level);
public ValidationLevel getLevel();
public Validation setSchema(String schema);
public String getSchema();
}
}Usage:
Schema schema = session.getSchema("mydb");
// Get collection (create if doesn't exist)
Collection users = schema.createCollection("users", true);
// Get existing collection
Collection products = schema.getCollection("products");
// Get collection with existence check
try {
Collection orders = schema.getCollection("orders", true);
} catch (XDevAPIError e) {
System.out.println("Collection does not exist");
}
// Create collection with validation
Schema.CreateCollectionOptions options = new Schema.CreateCollectionOptions()
.setReuseExisting(true)
.setValidation(new Schema.Validation()
.setLevel(Schema.Validation.ValidationLevel.STRICT)
.setSchema("{\"type\": \"object\", \"properties\": {\"name\": {\"type\": \"string\"}}}"));
Collection validatedColl = schema.createCollection("validated_users", options);
// Modify collection validation
Schema.ModifyCollectionOptions modifyOptions = new Schema.ModifyCollectionOptions()
.setValidation(new Schema.Validation()
.setLevel(Schema.Validation.ValidationLevel.OFF));
schema.modifyCollection("validated_users", modifyOptions);
// List all collections
List<Collection> collections = schema.getCollections();
for (Collection coll : collections) {
System.out.println("Collection: " + coll.getName());
}
// List collections matching pattern
List<Collection> userCollections = schema.getCollections("user%");
// Drop collection
schema.dropCollection("temp_collection");
// Get table
Table employees = schema.getTable("employees");
// List all tables
List<Table> tables = schema.getTables();
for (Table table : tables) {
System.out.println("Table: " + table.getName());
}Collection interface for document operations.
package com.mysql.cj.xdevapi;
public interface Collection extends DatabaseObject {
// Document operations
AddStatement add(DbDoc document);
AddStatement add(DbDoc... docs);
AddStatement add(String... jsonStrings);
AddStatement add(Map<String, ?> docMap);
FindStatement find();
FindStatement find(String searchCondition);
ModifyStatement modify(String searchCondition);
RemoveStatement remove(String searchCondition);
// Document retrieval
DbDoc getOne(String id);
DbDoc newDoc();
// Index management
Result createIndex(String indexName, String indexDefinition);
Result createIndex(String indexName, DbDoc indexDefinition);
void dropIndex(String indexName);
// Collection metadata
String getName();
Schema getSchema();
Session getSession();
boolean existsInDatabase();
// Document count
long count();
// Replace one document
Result replaceOne(String id, DbDoc doc);
Result replaceOne(String id, String jsonString);
// Add or replace one document
Result addOrReplaceOne(String id, DbDoc doc);
Result addOrReplaceOne(String id, String jsonString);
// Remove one document
Result removeOne(String id);
}
public class CollectionImpl implements Collection {
// Implementation of Collection interface
public AddStatement add(DbDoc... docs);
public AddStatement add(String... jsonStrings);
public AddStatement add(Map<String, ?> docMap);
public FindStatement find();
public FindStatement find(String searchCondition);
public ModifyStatement modify(String searchCondition);
public RemoveStatement remove(String searchCondition);
public DbDoc getOne(String id);
public DbDoc newDoc();
public Result createIndex(String indexName, String indexDefinition);
public Result createIndex(String indexName, DbDoc indexDefinition);
public void dropIndex(String indexName);
public String getName();
public Schema getSchema();
public Session getSession();
public boolean existsInDatabase();
public long count();
public Result replaceOne(String id, DbDoc doc);
public Result replaceOne(String id, String jsonString);
public Result addOrReplaceOne(String id, DbDoc doc);
public Result addOrReplaceOne(String id, String jsonString);
public Result removeOne(String id);
}Usage:
Schema schema = session.getSchema("mydb");
Collection users = schema.getCollection("users");
// Add document
DbDoc newUser = users.newDoc()
.add("name", new JsonString().setValue("Alice"))
.add("age", new JsonNumber().setValue("30"))
.add("email", new JsonString().setValue("alice@example.com"));
AddResult addResult = users.add(newUser).execute();
// Add JSON string
users.add("{\"name\": \"Bob\", \"age\": 25}").execute();
// Add multiple documents
users.add(
"{\"name\": \"Charlie\", \"age\": 35}",
"{\"name\": \"David\", \"age\": 28}"
).execute();
// Find documents
DocResult result = users.find("age > :minAge")
.bind("minAge", 25)
.execute();
// Get one document by ID
DbDoc user = users.getOne("00005f3a6b7700000000000000000001");
// Count documents
long count = users.count();
// Replace one document
DbDoc updatedUser = users.newDoc()
.add("name", new JsonString().setValue("Alice Updated"))
.add("age", new JsonNumber().setValue("31"));
users.replaceOne("00005f3a6b7700000000000000000001", updatedUser);
// Remove one document
users.removeOne("00005f3a6b7700000000000000000002");
// Create index
String indexDef = "{\"fields\": [{\"field\": \"$.age\", \"type\": \"INT\"}]}";
users.createIndex("age_idx", indexDef);
// Drop index
users.dropIndex("age_idx");Table interface for relational operations.
package com.mysql.cj.xdevapi;
public interface Table extends DatabaseObject {
// Data manipulation
InsertStatement insert();
InsertStatement insert(String... projection);
InsertStatement insert(Map<String, Object> fieldsAndValues);
SelectStatement select(String... projection);
UpdateStatement update();
DeleteStatement delete();
// Table metadata
String getName();
Schema getSchema();
Session getSession();
boolean existsInDatabase();
boolean isView();
// Row count
long count();
}Usage:
Schema schema = session.getSchema("mydb");
Table employees = schema.getTable("employees");
// Insert row
employees.insert("name", "age", "department")
.values("Alice", 30, "Engineering")
.execute();
// Insert multiple rows
employees.insert("name", "age", "department")
.values("Bob", 25, "Sales")
.values("Charlie", 35, "Marketing")
.execute();
// Select rows
RowResult rows = employees.select("name", "age", "department")
.where("age > :minAge")
.bind("minAge", 25)
.orderBy("age DESC")
.execute();
while (rows.hasNext()) {
Row row = rows.next();
System.out.println(row.getString("name") + " - " + row.getInt("age"));
}
// Update rows
employees.update()
.set("age", 31)
.where("name = :name")
.bind("name", "Alice")
.execute();
// Delete rows
employees.delete()
.where("age < :minAge")
.bind("minAge", 25)
.execute();
// Count rows
long totalEmployees = employees.count();
// Check if table is a view
boolean isView = employees.isView();Base interface for database objects.
package com.mysql.cj.xdevapi;
public interface DatabaseObject {
// Get object name
String getName();
// Get parent schema
Schema getSchema();
// Get session
Session getSession();
// Check existence
boolean existsInDatabase();
}Interface for JSON document objects.
package com.mysql.cj.xdevapi;
import java.util.Map;
import java.util.Set;
public interface DbDoc extends JsonValue, Map<String, JsonValue> {
// Add key-value pair
DbDoc add(String key, JsonValue value);
// Get value by key (inherited from Map)
JsonValue get(Object key);
// Remove key (inherited from Map)
JsonValue remove(Object key);
// Get document size (inherited from Map)
int size();
// Get all keys (inherited from Map)
Set<String> keySet();
// Convert to JSON string
String toString();
// Convert to formatted JSON string (inherited from JsonValue)
String toFormattedString();
}
public class DbDocImpl implements DbDoc {
// Constructor
public DbDocImpl();
public DbDocImpl(String jsonString);
public DbDocImpl(Map<String, ?> map);
// Implementation
public DbDoc add(String key, JsonValue value);
public JsonValue get(String key);
public JsonValue remove(String key);
public int size();
public Set<String> keySet();
public String toString();
public String toFormattedString();
}Usage:
// Create document
DbDoc doc = new DbDocImpl();
doc.add("name", new JsonString().setValue("Alice"));
doc.add("age", new JsonNumber().setValue("30"));
doc.add("active", JsonLiteral.TRUE);
// Create from JSON string
DbDoc doc2 = new DbDocImpl("{\"name\": \"Bob\", \"age\": 25}");
// Create from map
Map<String, Object> map = new HashMap<>();
map.put("name", "Charlie");
map.put("age", 35);
DbDoc doc3 = new DbDocImpl(map);
// Access values
JsonValue name = doc.get("name");
if (name instanceof JsonString) {
System.out.println("Name: " + ((JsonString) name).getString());
}
// Remove key
doc.remove("active");
// Get all keys
Set<String> keys = doc.keySet();
for (String key : keys) {
System.out.println(key + ": " + doc.get(key));
}
// Convert to JSON string
String json = doc.toString();
System.out.println(json);
// Formatted output
String formatted = doc.toFormattedString();
System.out.println(formatted);Interfaces and classes for JSON values.
package com.mysql.cj.xdevapi;
public interface JsonValue {
// Base interface for all JSON values
// Get formatted JSON string
default String toFormattedString() {
return toString();
}
}
public class JsonString implements JsonValue {
// Constructor
public JsonString();
// Set value
public JsonString setValue(String value);
// Get value
public String getString();
// String representation
public String toString();
}
public class JsonNumber implements JsonValue {
// Constructor
public JsonNumber();
// Set value
public JsonNumber setValue(String value);
// Get value
public String getString();
public Integer getInteger();
public Long getLong();
public BigDecimal getBigDecimal();
// String representation
public String toString();
}
public class JsonArray extends ArrayList<JsonValue> implements JsonValue {
// Constructor
public JsonArray();
// Add value (convenience method)
public JsonArray addValue(JsonValue val);
// Inherited from ArrayList:
// public boolean add(JsonValue val);
// public JsonValue get(int index);
// public int size();
// public JsonValue remove(int index);
// public void clear();
// ... and all other ArrayList methods
// String representation
public String toString();
public String toFormattedString();
}
public enum JsonLiteral implements JsonValue {
TRUE("true"),
FALSE("false"),
NULL("null");
private final String value;
JsonLiteral(String value) {
this.value = value;
}
public String toString() {
return this.value;
}
}Usage:
// String value
JsonString name = new JsonString().setValue("Alice");
System.out.println(name.getString()); // "Alice"
// Number value
JsonNumber age = new JsonNumber().setValue("30");
System.out.println(age.getInteger()); // 30
JsonNumber price = new JsonNumber().setValue("19.99");
System.out.println(price.getBigDecimal()); // 19.99
// Array value
JsonArray hobbies = new JsonArray();
hobbies.add(new JsonString().setValue("reading"));
hobbies.add(new JsonString().setValue("coding"));
hobbies.add(new JsonString().setValue("gaming"));
System.out.println(hobbies.size()); // 3
// Literal values
JsonValue isActive = JsonLiteral.TRUE;
JsonValue nothing = JsonLiteral.NULL;
// Build document with all types
DbDoc user = new DbDocImpl();
user.add("name", name);
user.add("age", age);
user.add("hobbies", hobbies);
user.add("active", isActive);
user.add("middleName", JsonLiteral.NULL);Utility class for parsing JSON strings into DbDoc and JsonArray objects.
package com.mysql.cj.xdevapi;
import java.io.IOException;
import java.io.StringReader;
public class JsonParser {
// Parse JSON string into DbDoc
public static DbDoc parseDoc(String jsonString);
// Parse JSON string into DbDoc (with reader)
public static DbDoc parseDoc(StringReader reader) throws IOException;
// Parse JSON array string into JsonArray (with reader)
public static JsonArray parseArray(StringReader reader) throws IOException;
}Usage:
// Parse JSON string to DbDoc
String jsonString = "{\"name\": \"Alice\", \"age\": 30, \"active\": true}";
DbDoc doc = JsonParser.parseDoc(jsonString);
// Access parsed values
JsonValue nameValue = doc.get("name");
if (nameValue instanceof JsonString) {
System.out.println("Name: " + ((JsonString) nameValue).getString());
}
// Parse with StringReader for advanced use cases
StringReader reader = new StringReader("{\"city\": \"New York\", \"zip\": 10001}");
try {
DbDoc addressDoc = JsonParser.parseDoc(reader);
System.out.println(addressDoc.toString());
} catch (IOException e) {
e.printStackTrace();
}Interface for result set column metadata.
package com.mysql.cj.xdevapi;
public interface Column {
// Column identification
String getSchemaName();
String getTableName();
String getTableLabel();
String getColumnName();
String getColumnLabel();
// Type information
Type getType();
long getLength();
int getFractionalDigits();
// Numeric properties
boolean isNumberSigned();
// String properties
String getCollationName();
String getCharacterSetName();
boolean isPadded();
// Column properties
boolean isNullable();
boolean isAutoIncrement();
boolean isPrimaryKey();
boolean isUniqueKey();
boolean isPartKey();
}
public class ColumnImpl implements Column {
// Implementation of Column interface
public ColumnImpl(com.mysql.cj.result.Field field);
public String getSchemaName();
public String getTableName();
public String getTableLabel();
public String getColumnName();
public String getColumnLabel();
public Type getType();
public long getLength();
public int getFractionalDigits();
public boolean isNumberSigned();
public String getCollationName();
public String getCharacterSetName();
public boolean isPadded();
public boolean isNullable();
public boolean isAutoIncrement();
public boolean isPrimaryKey();
public boolean isUniqueKey();
public boolean isPartKey();
}
public enum Type {
// Column types
BIT,
TINYINT,
SMALLINT,
MEDIUMINT,
INT,
BIGINT,
FLOAT,
DECIMAL,
DOUBLE,
JSON,
STRING,
BYTES,
TIME,
DATE,
DATETIME,
TIMESTAMP,
SET,
ENUM,
GEOMETRY;
}Interface for result row access.
package com.mysql.cj.xdevapi;
public interface Row {
// Get value by position
Object getObject(int pos);
// Get value by name
Object getObject(String columnName);
// Convert to DbDoc
DbDoc toDbDoc();
// String values
String getString(int pos);
String getString(String columnName);
// Numeric values
int getInt(int pos);
int getInt(String columnName);
long getLong(int pos);
long getLong(String columnName);
double getDouble(int pos);
double getDouble(String columnName);
BigDecimal getBigDecimal(int pos);
BigDecimal getBigDecimal(String columnName);
// Boolean values
boolean getBoolean(int pos);
boolean getBoolean(String columnName);
// Binary values
byte[] getBytes(int pos);
byte[] getBytes(String columnName);
// Date/Time values
Date getDate(int pos);
Date getDate(String columnName);
Timestamp getTimestamp(int pos);
Timestamp getTimestamp(String columnName);
Time getTime(int pos);
Time getTime(String columnName);
}
public class RowImpl implements Row {
// Implementation of Row interface
public Object getObject(int pos);
public Object getObject(String columnName);
public DbDoc toDbDoc();
public String getString(int pos);
public String getString(String columnName);
public int getInt(int pos);
public int getInt(String columnName);
public long getLong(int pos);
public long getLong(String columnName);
public double getDouble(int pos);
public double getDouble(String columnName);
public BigDecimal getBigDecimal(int pos);
public BigDecimal getBigDecimal(String columnName);
public boolean getBoolean(int pos);
public boolean getBoolean(String columnName);
public byte[] getBytes(int pos);
public byte[] getBytes(String columnName);
public Date getDate(int pos);
public Date getDate(String columnName);
public Timestamp getTimestamp(int pos);
public Timestamp getTimestamp(String columnName);
public Time getTime(int pos);
public Time getTime(String columnName);
}Interface for server warnings.
package com.mysql.cj.xdevapi;
public interface Warning {
// Get warning level
int getLevel();
// Get warning code
long getCode();
// Get warning message
String getMessage();
}
public class WarningImpl implements Warning {
// Implementation of Warning interface
public WarningImpl(int level, long code, String message);
public int getLevel();
public long getCode();
public String getMessage();
}Wrapper for expression strings used in queries.
package com.mysql.cj.xdevapi;
public class Expression {
// Create expression from string
public static Expression expr(String expressionString);
// Get expression string
public String getExpressionString();
}Usage:
// Use expression in find
Collection users = schema.getCollection("users");
DocResult result = users.find("age > 25")
.fields(Expression.expr("name"), Expression.expr("age * 2 as doubleAge"))
.execute();
// Use expression in modify
users.modify("_id = :id")
.set("visits", Expression.expr("visits + 1"))
.bind("id", "someId")
.execute();
// Use expression in select
Table employees = schema.getTable("employees");
RowResult rows = employees.select("name", "salary")
.where(Expression.expr("salary > 50000 AND department = 'Engineering'"))
.execute();Description of database objects returned from list operations.
package com.mysql.cj.xdevapi;
public class DatabaseObjectDescription {
// Constructor
public DatabaseObjectDescription(String name, String type);
// Get object name
public String getObjectName();
// Get object type
public String getObjectType();
}Install with Tessl CLI
npx tessl i tessl/maven-com-mysql--mysql-connector-j