vertx-mysql-client/java/
Reactive MySQL Client是MySQL的客户端,它具有直接的API,专注于可伸缩性和低开销。
特征
事件驱动
轻巧的
内置连接池
准备查询缓存
游标支持
行流
RxJava 1和RxJava 2
直接存储到对象,没有不必要的副本
Java 8日期和时间
存储过程支持
TLS / SSL支持
MySQL实用程序命令支持
使用MySQL和MariaDB
丰富的排序规则和字符集支持
用法
要使用反应性MySQL客户端,请将以下依赖项添加到构建描述符的“ 依赖项”部分:
Maven(在您的中
pom.xml):
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-mysql-client</artifactId>
<version>3.8.4</version>
</dependency>
Gradle(在您的
build.gradle文件中):
dependencies {
compile 'io.vertx:vertx-mysql-client:3.8.4'
}
入门
这是连接,查询和断开连接的最简单方法
MySQLConnectOptions connectOptions = new MySQLConnectOptions()
.setPort(3306)
.setHost("the-host")
.setDatabase("the-db")
.setUser("user")
.setPassword("secret");
// Pool options
PoolOptions poolOptions = new PoolOptions()
.setMaxSize(5);
// Create the client pool
MySQLPool client = MySQLPool.pool(connectOptions, poolOptions);
// A simple query
client.query("SELECT * FROM users WHERE id='julien'", ar -> {
if (ar.succeeded()) {
RowSet<Row> result = ar.result();
System.out.println("Got " + result.size() + " rows ");
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
// Now close the pool
client.close();
});
连接到MySQL
大多数时候,您将使用池连接到MySQL:
MySQLConnectOptions connectOptions = new MySQLConnectOptions()
.setPort(3306)
.setHost("the-host")
.setDatabase("the-db")
.setUser("user")
.setPassword("secret");
// Pool options
PoolOptions poolOptions = new PoolOptions()
.setMaxSize(5);
// Create the pooled client
MySQLPool client = MySQLPool.pool(connectOptions, poolOptions);
池化的客户端使用连接池,任何操作都将从池中借用连接以执行该操作并将其释放到池中。
如果使用Vert.x运行,则可以将其传递给您的Vertx实例:
MySQLConnectOptions connectOptions = new MySQLConnectOptions()
.setPort(3306)
.setHost("the-host")
.setDatabase("the-db")
.setUser("user")
.setPassword("secret");
// Pool options
PoolOptions poolOptions = new PoolOptions()
.setMaxSize(5);
// Create the pooled client
MySQLPool client = MySQLPool.pool(vertx, connectOptions, poolOptions);
当您不再需要池时,您需要释放它:
pool.close();
当您需要在同一连接上执行多个操作时,需要使用一个client connection。
您可以轻松地从游泳池中获得一个:
MySQLConnectOptions connectOptions = new MySQLConnectOptions()
.setPort(3306)
.setHost("the-host")
.setDatabase("the-db")
.setUser("user")
.setPassword("secret");
// Pool options
PoolOptions poolOptions = new PoolOptions()
.setMaxSize(5);
// Create the pooled client
MySQLPool client = MySQLPool.pool(vertx, connectOptions, poolOptions);
// Get a connection from the pool
client.getConnection(ar1 -> {
if (ar1.succeeded()) {
System.out.println("Connected");
// Obtain our connection
SqlConnection conn = ar1.result();
// All operations execute on the same connection
conn.query("SELECT * FROM users WHERE id='julien'", ar2 -> {
if (ar2.succeeded()) {
conn.query("SELECT * FROM users WHERE id='emad'", ar3 -> {
// Release the connection to the pool
conn.close();
});
} else {
// Release the connection to the pool
conn.close();
}
});
} else {
System.out.println("Could not connect: " + ar1.cause().getMessage());
}
});
完成连接后,必须关闭它才能将其释放到池中,以便可以重用它。
组态
您可以通过多种方法来配置客户端。
数据对象
配置客户端的一种简单方法是指定MySQLConnectOptions数据对象。
MySQLConnectOptions connectOptions = new MySQLConnectOptions()
.setPort(3306)
.setHost("the-host")
.setDatabase("the-db")
.setUser("user")
.setPassword("secret");
// Pool Options
PoolOptions poolOptions = new PoolOptions().setMaxSize(5);
// Create the pool from the data object
MySQLPool pool = MySQLPool.pool(vertx, connectOptions, poolOptions);
pool.getConnection(ar -> {
// Handling your connection
});
排序规则和字符集
Reactive MySQL客户端支持配置排序规则或字符集,并将它们映射到相关的java.nio.charset.Charset。例如,您可以为类似的连接指定字符集
MySQLConnectOptions connectOptions = new MySQLConnectOptions();
// set connection character set to utf8 instead of the default charset utf8mb4
connectOptions.setCharset("utf8");
您也可以为连接指定排序规则,例如
MySQLConnectOptions connectOptions = new MySQLConnectOptions();
// set connection collation to utf8_general_ci instead of the default collation utf8mb4_general_ci
// setting a collation will override the charset option
connectOptions.setCharset("gbk");
connectOptions.setCollation("utf8_general_ci");
MySQL将utf8mb4作为默认字符集。请注意,在数据对象上设置排序规则将覆盖charset选项。
您可以执行SQL SHOW COLLATION;或SHOW CHARACTER SET;获取受支持的排序规则和字符集。
有关MySQL字符集和排序规则的更多信息,请参见《MySQL参考手册》。
连接属性
您也可以使用setProperties或addProperty方法配置连接属性。注意setProperties将覆盖默认的客户端属性。
MySQLConnectOptions connectOptions = new MySQLConnectOptions();
// Add a connection attribute
connectOptions.addProperty("_java_version", "1.8.0_212");
// Override the attributes
Map<String, String> attributes = new HashMap<>();
attributes.put("_client_name", "myapp");
attributes.put("_client_version", "1.0.0");
connectOptions.setProperties(attributes);
有关客户端连接属性的更多信息,请参见《MySQL参考手册》。
useAffectedRows
您可以配置useAffectedRows选项,以决定CLIENT_FOUND_ROWS在连接到服务器时是否设置标志。如果CLIENT_FOUND_ROWS指定了标志,则受影响的行数是找到的而不是受影响的行的数值。
有关更多信息,请参见《MySQL参考手册》。
连接URI
除了使用MySQLConnectOptions数据对象进行配置之外,当您要使用连接URI进行配置时,我们还为您提供了另一种连接方法:
String connectionUri = "mysql://dbuser:secretpassword@database.server.com:3211/mydb";
// Create the pool from the connection URI
MySQLPool pool = MySQLPool.pool(connectionUri);
// Create the connection from the connection URI
MySQLConnection.connect(vertx, connectionUri, res -> {
// Handling your connection
});
有关连接字符串格式的更多信息,请参见《MySQL参考手册》。
当前客户端在连接uri中支持以下参数关键字(关键字不区分大小写)
主办
港口
用户
密码
图式
插座
useAffectedRows
运行查询
当您不需要事务或运行单个查询时,可以直接在池上运行查询。池将使用其连接之一来运行查询并将结果返回给您。
这是运行简单查询的方法:
client.query("SELECT * FROM users WHERE id='julien'", ar -> {
if (ar.succeeded()) {
RowSet<Row> result = ar.result();
System.out.println("Got " + result.size() + " rows ");
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
准备好的查询
您可以对准备好的查询执行相同的操作。
SQL字符串可以使用数据库语法“?”按位置引用参数。
client.preparedQuery("SELECT * FROM users WHERE id=?", Tuple.of("julien"), ar -> {
if (ar.succeeded()) {
RowSet<Row> rows = ar.result();
System.out.println("Got " + rows.size() + " rows ");
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
查询方法提供了一个RowSet适用于SELECT查询的异步实例
client.preparedQuery("SELECT first_name, last_name FROM users", ar -> {
if (ar.succeeded()) {
RowSet<Row> rows = ar.result();
for (Row row : rows) {
System.out.println("User " + row.getString(0) + " " + row.getString(1));
}
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
或UPDATE / INSERT查询:
client.preparedQuery("INSERT INTO users (first_name, last_name) VALUES (?, ?)", Tuple.of("Julien", "Viet"), ar -> {
if (ar.succeeded()) {
RowSet<Row> rows = ar.result();
System.out.println(rows.rowCount());
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
可Row让您按索引访问数据
System.out.println("User " + row.getString(0) + " " + row.getString(1));
或按名称
System.out.println("User " + row.getString("first_name") + " " + row.getString("last_name"));
客户端不会在这里做任何魔术,并且无论您的SQL文本如何,列名都将用表中的名称标识。
您可以访问多种类型
String firstName = row.getString("first_name");
Boolean male = row.getBoolean("male");
Integer age = row.getInteger("age");
您可以缓存准备好的查询:
connectOptions.setCachePreparedStatements(true);
分批
您可以执行准备好的批处理
List<Tuple> batch = new ArrayList<>();
batch.add(Tuple.of("julien", "Julien Viet"));
batch.add(Tuple.of("emad", "Emad Alblueshi"));
// Execute the prepared batch
client.preparedBatch("INSERT INTO USERS (id, name) VALUES (?, ?)", batch, res -> {
if (res.succeeded()) {
// Process rows
RowSet<Row> rows = res.result();
} else {
System.out.println("Batch failed " + res.cause());
}
});
MySQL LAST_INSERT_ID
如果在表中插入一条记录,则可以获得自动递增的值。
client.query("INSERT INTO test(val) VALUES ('v1')", ar -> {
if (ar.succeeded()) {
RowSet<Row> rows = ar.result();
int lastInsertId = rows.property(MySQLClient.LAST_INSERTED_ID);
System.out.println("Last inserted id is: " + lastInsertId);
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
有关更多信息,请参见如何获取最后插入行的唯一ID。
使用连接
当需要执行顺序查询(不执行事务)时,可以创建一个新连接或从池中借用一个:
pool.getConnection(ar1 -> {
if (ar1.succeeded()) {
SqlConnection connection = ar1.result();
connection.query("SELECT * FROM users WHERE id='julien'", ar2 -> {
if (ar1.succeeded()) {
connection.query("SELECT * FROM users WHERE id='paulo'", ar3 -> {
// Do something with rows and return the connection to the pool
connection.close();
});
} else {
// Return the connection to the pool
connection.close();
}
});
}
});
可以创建准备好的查询:
connection.prepare("SELECT * FROM users WHERE first_name LIKE ?", ar1 -> {
if (ar1.succeeded()) {
PreparedQuery pq = ar1.result();
pq.execute(Tuple.of("julien"), ar2 -> {
if (ar2.succeeded()) {
// All rows
RowSet<Row> rows = ar2.result();
}
});
}
});
|
注意
|
准备好的查询缓存取决于,setCachePreparedStatements而不取决于您是创建准备好的查询还是使用direct prepared queries |
PreparedQuery 可以执行有效的批处理:
connection.prepare("INSERT INTO USERS (id, name) VALUES (?, ?)", ar1 -> {
if (ar1.succeeded()) {
PreparedQuery prepared = ar1.result();
// Create a query : bind parameters
List<Tuple> batch = new ArrayList();
// Add commands to the createBatch
batch.add(Tuple.of("julien", "Julien Viet"));
batch.add(Tuple.of("emad", "Emad Alblueshi"));
prepared.batch(batch, res -> {
if (res.succeeded()) {
// Process rows
RowSet<Row> rows = res.result();
} else {
System.out.println("Batch failed " + res.cause());
}
});
}
});
使用交易
连接交易
您可以使用SQL BEGIN/ COMMIT/ 执行事务ROLLBACK,如果这样做,则必须使用SqlConnection和自己进行管理。
或者,您可以使用的交易API SqlConnection:
pool.getConnection(res -> {
if (res.succeeded()) {
// Transaction must use a connection
SqlConnection conn = res.result();
// Begin the transaction
Transaction tx = conn.begin();
// Various statements
conn.query("INSERT INTO Users (first_name,last_name) VALUES ('Julien','Viet')", ar1 -> {
if (ar1.succeeded()) {
conn.query("INSERT INTO Users (first_name,last_name) VALUES ('Emad','Alblueshi')", ar2 -> {
if (ar2.succeeded()) {
// Commit the transaction
tx.commit(ar3 -> {
if (ar3.succeeded()) {
System.out.println("Transaction succeeded");
} else {
System.out.println("Transaction failed " + ar3.cause().getMessage());
}
// Return the connection to the pool
conn.close();
});
} else {
// Return the connection to the pool
conn.close();
}
});
} else {
// Return the connection to the pool
conn.close();
}
});
}
});
当PostgreSQL报告当前事务失败时(例如,臭名昭著的当前事务被中止,命令被忽略直到事务块结束),事务被回滚并被abortHandler 调用:
tx.abortHandler(v -> {
System.out.println("Transaction failed => rollbacked");
});
简化的交易API
使用池时,可以直接在池上启动事务。
它从池中借用连接,开始事务,并在事务结束时释放与池的连接。
pool.begin(res -> {
if (res.succeeded()) {
// Get the transaction
Transaction tx = res.result();
// Various statements
tx.query("INSERT INTO Users (first_name,last_name) VALUES ('Julien','Viet')", ar1 -> {
if (ar1.succeeded()) {
tx.query("INSERT INTO Users (first_name,last_name) VALUES ('Emad','Alblueshi')", ar2 -> {
if (ar2.succeeded()) {
// Commit the transaction
// the connection will automatically return to the pool
tx.commit(ar3 -> {
if (ar3.succeeded()) {
System.out.println("Transaction succeeded");
} else {
System.out.println("Transaction failed " + ar3.cause().getMessage());
}
});
}
});
} else {
// No need to close connection as transaction will abort and be returned to the pool
}
});
}
});
|
注意
|
此代码不会关闭连接,因为在事务处理时它将始终释放回池中 |
游标和流
默认情况下,准备好的查询执行会提取所有行,您可以使用 Cursor来控制要读取的行数:
connection.prepare("SELECT * FROM users WHERE age > ?", ar1 -> {
if (ar1.succeeded()) {
PreparedQuery pq = ar1.result();
// Create a cursor
Cursor cursor = pq.cursor(Tuple.of(18));
// Read 50 rows
cursor.read(50, ar2 -> {
if (ar2.succeeded()) {
RowSet<Row> rows = ar2.result();
// Check for more ?
if (cursor.hasMore()) {
// Repeat the process...
} else {
// No more rows - close the cursor
cursor.close();
}
}
});
}
});
游标过早释放时应将其关闭:
cursor.read(50, ar2 -> {
if (ar2.succeeded()) {
// Close the cursor
cursor.close();
}
});
还可以为游标提供流API,这会更加方便,特别是对于Rxified版本而言。
connection.prepare("SELECT * FROM users WHERE age > ?", ar1 -> {
if (ar1.succeeded()) {
PreparedQuery pq = ar1.result();
// Fetch 50 rows at a time
RowStream<Row> stream = pq.createStream(50, Tuple.of(18));
// Use the stream
stream.exceptionHandler(err -> {
System.out.println("Error: " + err.getMessage());
});
stream.endHandler(v -> {
System.out.println("End of stream");
});
stream.handler(row -> {
System.out.println("User: " + row.getString("last_name"));
});
}
});
流将批量读取行50并将其流化,将行传递到处理程序后,将50读取新一批,依此类推。
可以恢复或暂停该流,已加载的行将保留在内存中,直到被传递为止,并且游标将停止迭代。
MySQL类型映射
当前客户端支持以下MySQL类型
BOOL,BOOLEAN(
java.lang.Byte)忍者(
java.lang.Byte)SMALLINT(
java.lang.Short)MEDIUMINT(
java.lang.Integer)INT,INTEGER(
java.lang.Integer)币种(
java.lang.Long)浮标(
java.lang.Float)双(
java.lang.Double)数值(
io.vertx.sqlclient.data.Numeric)日期(
java.time.LocalDate)DATETIME(
java.time.LocalDateTime)时间(
java.time.Duration)时间戳(
java.time.LocalDateTime)年(
java.lang.Short)字符(
java.lang.String)VARCHAR(
java.lang.String)二进制(
io.vertx.core.buffer.Buffer)VARBINARY(
io.vertx.core.buffer.Buffer)天黑宝(
io.vertx.core.buffer.Buffer)TINYTEXT(
java.lang.String)BLOB(
io.vertx.core.buffer.Buffer)文字(
java.lang.String)中号(
io.vertx.core.buffer.Buffer)MEDIUMTEXT(
java.lang.String)LONGBLOB(
io.vertx.core.buffer.Buffer)长文本(
java.lang.String)枚举(
java.lang.String)设定(
java.lang.String)JSON( ,
io.vertx.core.json.JsonObject,io.vertx.core.json.JsonArray,Number,Boolean,)Stringio.vertx.sqlclient.Tuple#JSON_NULL
存储值时,元组解码使用上述类型
处理布尔
在MySQL中BOOLEAN,BOOL数据类型是的同义词TINYINT(1)。零值视为假,非零值视为真。一个BOOLEAN数据类型值存储在Row或Tuple作为java.lang.Byte类型,你可以调用Row#getValue来检索它的java.lang.Byte值,或者可以称之为Row#getBoolean检索它java.lang.Boolean的价值。
client.query("SELECT graduated FROM students WHERE id = 0", ar -> {
if (ar.succeeded()) {
RowSet<Row> rowSet = ar.result();
for (Row row : rowSet) {
int pos = row.getColumnIndex("graduated");
Byte value = row.get(Byte.class, pos);
Boolean graduated = row.getBoolean("graduated");
}
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
当您要使用参数BOOLEAN值执行准备好的语句时,只需将java.lang.Boolean值添加到参数列表中即可。
client.preparedQuery("UPDATE students SET graduated = ? WHERE id = 0", Tuple.of(true), ar -> {
if (ar.succeeded()) {
System.out.println("Updated with the boolean value");
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
处理JSON
MySQL JSON数据类型由以下Java类型表示:
StringNumberBooleanio.vertx.core.json.JsonObjectio.vertx.core.json.JsonArrayio.vertx.sqlclient.Tuple#JSON_NULL用于表示JSON空文字
Tuple tuple = Tuple.of(
Tuple.JSON_NULL,
new JsonObject().put("foo", "bar"),
3);
// Retrieving json
Object value = tuple.getValue(0); // Expect JSON_NULL
//
value = tuple.get(JsonObject.class, 1); // Expect JSON object
//
value = tuple.get(Integer.class, 2); // Expect 3
value = tuple.getInteger(2); // Expect 3
处理NUMERIC
该NumericJava类型用于表示MySQL的NUMERIC类型。
Numeric numeric = row.get(Numeric.class, 0);
if (numeric.isNaN()) {
// Handle NaN
} else {
BigDecimal value = numeric.bigDecimalValue();
}
收集器查询
您可以将Java收集器与查询API结合使用:
Collector<Row, ?, Map<Long, String>> collector = Collectors.toMap(
row -> row.getLong("id"),
row -> row.getString("last_name"));
// Run the query with the collector
client.query("SELECT * FROM users",
collector,
ar -> {
if (ar.succeeded()) {
SqlResult<Map<Long, String>> result = ar.result();
// Get the map created by the collector
Map<Long, String> map = result.value();
System.out.println("Got " + map);
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
收集器处理不得保留引用,Row因为只有一行用于处理整个集合。
Java Collectors提供了许多有趣的预定义收集器,例如,您可以直接从行集中轻松创建一个字符串:
Collector<Row, ?, String> collector = Collectors.mapping(
row -> row.getString("last_name"),
Collectors.joining(",", "(", ")")
);
// Run the query with the collector
client.query("SELECT * FROM users",
collector,
ar -> {
if (ar.succeeded()) {
SqlResult<String> result = ar.result();
// Get the string created by the collector
String list = result.value();
System.out.println("Got " + list);
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
MySQL存储过程
您可以在查询中运行存储过程。结果将按照MySQL协议从服务器检索,这里没有任何魔术。
client.query("CREATE PROCEDURE multi() BEGIN\n" +
" SELECT 1;\n" +
" SELECT 1;\n" +
" INSERT INTO ins VALUES (1);\n" +
" INSERT INTO ins VALUES (2);\n" +
"END;", ar1 -> {
if (ar1.succeeded()) {
// create stored procedure success
client.query("CALL multi();", ar2 -> {
if (ar2.succeeded()) {
// handle the result
RowSet<Row> result1 = ar2.result();
Row row1 = result1.iterator().next();
System.out.println("First result: " + row1.getInteger(0));
RowSet<Row> result2 = result1.next();
Row row2 = result2.iterator().next();
System.out.println("Second result: " + row2.getInteger(0));
RowSet<Row> result3 = result2.next();
System.out.println("Affected rows: " + result3.rowCount());
} else {
System.out.println("Failure: " + ar2.cause().getMessage());
}
});
} else {
System.out.println("Failure: " + ar1.cause().getMessage());
}
});
注意:暂时不支持绑定OUT参数的预准备语句。
MySQL的本地文件
该客户端支持处理LOCAL INFILE请求,如果要将数据从本地文件加载到服务器中,则可以使用query LOAD DATA LOCAL INFILE '<filename>' INTO TABLE <table>;。更多信息可以在MySQL参考手册中找到。
认证方式
MySQL 8.0引入了一种新的身份验证方法caching_sha2_password,它是默认的身份验证方法。为了使用这种新的身份验证方法连接到服务器,您需要使用安全连接(即启用TLS / SSL)或使用RSA密钥对交换加密的密码,以避免密码泄漏。RSA密钥对在通信过程中会自动交换,但是服务器RSA公钥在此过程中可能会遭到黑客入侵,因为它是通过不安全的连接传输的。因此,如果您的连接不安全,并且希望避免暴露服务器RSA公钥的风险,则可以如下设置服务器RSA公钥:
MySQLConnectOptions options1 = new MySQLConnectOptions()
.setPort(3306)
.setHost("the-host")
.setDatabase("the-db")
.setUser("user")
.setPassword("secret")
.setServerRsaPublicKeyPath("tls/files/public_key.pem"); // configure with path of the public key
MySQLConnectOptions options2 = new MySQLConnectOptions()
.setPort(3306)
.setHost("the-host")
.setDatabase("the-db")
.setUser("user")
.setPassword("secret")
.setServerRsaPublicKeyValue(Buffer.buffer("-----BEGIN PUBLIC KEY-----\n" +
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3yvG5s0qrV7jxVlp0sMj\n" +
"xP0a6BuLKCMjb0o88hDsJ3xz7PpHNKazuEAfPxiRFVAV3edqfSiXoQw+lJf4haEG\n" +
"HQe12Nfhs+UhcAeTKXRlZP/JNmI+BGoBduQ1rCId9bKYbXn4pvyS/a1ft7SwFkhx\n" +
"aogCur7iIB0WUWvwkQ0fEj/Mlhw93lLVyx7hcGFq4FOAKFYr3A0xrHP1IdgnD8QZ\n" +
"0fUbgGLWWLOossKrbUP5HWko1ghLPIbfmU6o890oj1ZWQewj1Rs9Er92/UDj/JXx\n" +
"7ha1P+ZOgPBlV037KDQMS6cUh9vTablEHsMLhDZanymXzzjBkL+wH/b9cdL16LkQ\n" +
"5QIDAQAB\n" +
"-----END PUBLIC KEY-----\n")); // configure with buffer of the public key
有关caching_sha2_password身份验证方法的更多信息,请参见《MySQL参考手册》。
使用SSL / TLS
要配置客户端以使用SSL连接,您可以MySQLConnectOptions 像Vert.x这样进行配置NetClient。支持所有SSL模式,您可以进行配置sslmode。DISABLED默认情况下,客户端处于SSL模式。 ssl参数只是设置的捷径sslmode。setSsl(true)等同于setSslMode(VERIFY_CA)并setSsl(false)等同于setSslMode(DISABLED)。
MySQLConnectOptions options = new MySQLConnectOptions()
.setPort(3306)
.setHost("the-host")
.setDatabase("the-db")
.setUser("user")
.setPassword("secret")
.setSslMode(SslMode.VERIFY_CA)
.setPemTrustOptions(new PemTrustOptions().addCertPath("/path/to/cert.pem"));
MySQLConnection.connect(vertx, options, res -> {
if (res.succeeded()) {
// Connected with SSL
} else {
System.out.println("Could not connect " + res.cause());
}
});
可以在Vert.x文档中找到更多信息。
MySQL实用程序命令
有时您想使用MySQL实用程序命令,我们为此提供支持。可以在MySQL实用程序命令中找到更多信息。
COM_PING
您可以使用COM_PING命令来检查服务器是否处于活动状态。如果服务器响应PING,则将通知处理程序,否则将永远不会调用该处理程序。
connection.ping(ar -> {
System.out.println("The server has responded to the PING");
});
COM_RESET_CONNECTION
您可以使用COM_RESET_CONNECTION命令重置会话状态,这将重置连接状态,例如:-用户变量-临时表-准备好的语句
connection.resetConnection(ar -> {
if (ar.succeeded()) {
System.out.println("Connection has been reset now");
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
COM_CHANGE_USER
您可以更改当前连接的用户,这将执行重新认证并重置连接状态,如COM_RESET_CONNECTION。
MySQLAuthOptions authenticationOptions = new MySQLAuthOptions()
.setUser("newuser")
.setPassword("newpassword")
.setDatabase("newdatabase");
connection.changeUser(authenticationOptions, ar -> {
if (ar.succeeded()) {
System.out.println("User of current connection has been changed.");
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
COM_INIT_DB
您可以使用COM_INIT_DB命令更改连接的默认架构。
connection.specifySchema("newschema", ar -> {
if (ar.succeeded()) {
System.out.println("Default schema changed to newschema");
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
COM_STATISTICS
您可以使用COM_STATISTICS命令获取MySQL服务器中某些内部状态变量的可读字符串。
connection.getInternalStatistics(ar -> {
if (ar.succeeded()) {
System.out.println("Statistics: " + ar.result());
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
COM_DEBUG
您可以使用COM_DEBUG命令将调试信息转储到MySQL服务器的STDOUT。
connection.debug(ar -> {
if (ar.succeeded()) {
System.out.println("Debug info dumped to server's STDOUT");
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
COM_SET_OPTION
您可以使用COM_SET_OPTION命令设置当前连接的选项。目前只能CLIENT_MULTI_STATEMENTS设置。
例如,您可以CLIENT_MULTI_STATEMENTS使用此命令禁用。
connection.setOption(MySQLSetOption.MYSQL_OPTION_MULTI_STATEMENTS_OFF, ar -> {
if (ar.succeeded()) {
System.out.println("CLIENT_MULTI_STATEMENTS is off now");
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
MySQL和MariaDB版本支持表
| 的MySQL | 玛丽亚数据库 | ||
|---|---|---|---|
|
版 |
支持的 |
版 |
支持的 |
|
|
✔ |
|
✔ |
|
|
✔ |
|
✔ |
|
|
✔ |
|
✔ |
|
|
✔ |
|
✔ |
已知的问题:
重置连接实用程序命令在MySQL 5.5、5.6和MariaDB 10.1中不起作用
MariaDB 10.2和10.3不支持更改用户实用程序命令
vertx-mysql-client/java/的更多相关文章
- Reactive MySQL Client
Reactive MySQL Client是MySQL的客户端,具有直观的API,侧重于可伸缩性和低开销. 特征 事件驱动 轻量级 内置连接池 准备好的查询缓存 游标支持 行流 RxJava 1和Rx ...
- mysql 的 java 连接库
mysql 的 java 连接库 解压缩mysql-connector-java-5.1.30.zip 将要使用的是mysql-connector-java-5.1.30-bin-g.jar和mysq ...
- How to Allow MySQL Client to Connect to Remote MySql
How to Allow MySQL Client to Connect to Remote MySQ By default, MySQL does not allow remote clients ...
- 编译pure-ftpd时提示错误Your MySQL client libraries aren't properly installed
如果出现类似configure: error: Your MySQL client libraries aren’t properly installed 的错误,请将mysql目录下的 includ ...
- Mysql,Oracle,Java数据类型对应
Mysql Oracle Java BIGINT NUMBER(19,0) java.lang.Long BIT RAW byte[] BLOB BLOB RAW byte[] CHAR CHAR j ...
- configure: error: Cannot find libmysqlclient under /usr Note that the MySQL client library is not bundled anymore! 报错解决
错误说明 今天在centos 6.3 64位版本上安装PHP5.4.3时在./configure 步骤的时候出现了下面错误configure: error: Cannot find libmysqlc ...
- php编译错误Note that the MySQL client library is not bundled anymore或者cannot find mysql header file
rpm -ivh MySQL-devel-community-5.1.57-1.sles10.x86_64.rpm export PATH=/usr/local/services/libxml2-2. ...
- Linux Mysql Client 查询中文乱码
1.mysql client 端设置编码为utf8 set character_set_results=utf8; 2.连接linux的客户端的编码也要设置为utf8(比如xshell,putty等)
- php编译错误Note that the MySQL client library is not bundled anymore!
Note that the MySQL client library is not bundled anymore! 解决方法. 1. 查看系统有没有安装mysql header find / -na ...
- Mybatis异常处理之MySQL Connector Java] will not be managed by Spring
很长时间没写后台代码有点生疏了,这不今天又出点小插曲,写个文章记录下. 由于要上传点数据到后台,顺手整了个mybatis+springmvc.在保存数据时出现了异常. Creating a new S ...
随机推荐
- Python笔记:设计模式之工厂模式
工厂模式:“工厂”即表示一个负责创建其他类型的对象的类,通常情况下,一个工厂的对象会有一个或多个方法与之关联,这些方法用于创建不同类型的对象,工厂对象会根据客户端给方法传递的不同的参数或者客户端调用不 ...
- django4-模板进阶
1.模板系统的语法 引用变量数据: {{ }} 标签逻辑操作:{%...%} 2.变量 变量名由字符数字下划线组成 ,可以执行由视图函数传过来的对象的方法和属性 ,但是视图函数中如果使用 ' . ' ...
- WebService发布服务例子
import javax.jws.WebMethod; import javax.jws.WebService; @WebService public interface WebServiceI { ...
- 调用大漠插件发送QQ和微信消息 C#版
大漠插件:3.1233 找图,找色,识字,找字,窗口,按鼠标,按键盘 0.注册dm.dll: regsvr32 xxx\dm.dll 1.添加com引用: 2.dmsoft各种调用: 原理: 查找窗口 ...
- 02Javascript变量和数据类型
1. 变量概述 1.1 什么是变量 通俗:变量是用于存放数据的容器. 我们通过 变量名 获取数据,甚至数据可以修改. 1.2 变量在内存中的存储 本质:变量是程序在内存中申请的一块用来存放数据的空间. ...
- QT信号槽连接语法总结
信号槽是 Qt 框架引以为豪的机制之一. 所谓信号槽,实际就是观察者模式.当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal).这种触发是没有目的的,类似广播.如果 ...
- 元祖,range,字典,结构,fromkeys的使用
3.5.3 元祖 关键字 tuple tu=(1,2,3,'你好',True) print(tu) 元祖是有序,不可变数据,不能进行修改, 支持索引查看 存储一些比较重要的信息,在配置文件中使用 存放 ...
- 故障排除指南(TSG)-ORA-01552: Cannot Use System Rollback Segment for Non-System Tablespace (Doc ID 1579215.1)
Troubleshooting Guide (TSG) - ORA-01552: Cannot Use System Rollback Segment for Non-System Tablespac ...
- 5G浪潮来袭,程序员在风口中有何机遇
导读:本文共2894字,预计阅读时间为9分钟.通过阅读本文,你将了解到5G的优势.即将燃爆的领域以及程序员在快速发展的5G产业中所需关注的技术. 5G时代已经来临 随着中美5G主导权之战的持续发酵,5 ...
- CodeForces - 1007A (思维+双指针)
题意 https://vjudge.net/problem/CodeForces-1007A 对一个序列重排,使得新的数比原来的数大对应的位置个数最多. 思路 举个栗子,比如1 2 2 3 3 3 3 ...