Reactive MySQL Client
Reactive MySQL Client是MySQL的客户端,具有直观的API,侧重于可伸缩性和低开销。
特征
事件驱动
轻量级
内置连接池
准备好的查询缓存
游标支持
行流
RxJava 1和RxJava 2
将内存直接写入对象而不需要不必要
Java 8日期和时间
MySQL实用程序命令支持
兼容MySQL 5.6和5.7
用法
要使用Reactive MySQL Client,请将以下依赖项添加到构建描述符的dependencies部分:
Maven(在你的
pom.xml
):
<dependency><groupId>io.vertx</groupId><artifactId>vertx-mysql-client</artifactId> <version>3.8.0</version> </dependency>
Gradle(在您的
build.gradle
文件中):
dependencies {compile 'io.vertx:vertx-mysql-client:3.8.0' }
入门
这是连接,查询和断开连接的最简单方法
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 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();
当您需要在同一连接上执行多个操作时,您需要使用客户端 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 });
您还可以使用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参考手册。
连接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中的以下参数关键字
主办
港口
用户
密码
模式
插座
运行查询
当您不需要事务或运行单个查询时,您可以直接在池上运行查询; 池将使用其中一个连接来运行查询并将结果返回给您。
以下是如何运行简单查询:
client.query("SELECT * FROM users WHERE id='julien'", ar -> { if (ar.succeeded()) { RowSet result = ar.result(); System.out.println("Got " + result.size() + " rows "); } else { System.out.println("Failure: " + ar.cause().getMessage()); } });
您可以使用准备好的查询执行相同操作。
SQL字符串可以通过位置参考参数,使用$1
,$2
等...
client.preparedQuery("SELECT * FROM users WHERE id=?", Tuple.of("julien"), ar -> { if (ar.succeeded()) { RowSet 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 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 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"));
您可以访问各种类型
String firstName = row.getString("first_name"); Boolean male = row.getBoolean("male"); Integer age = row.getInteger("age");
您可以执行准备批处理
您可以缓存准备好的查询:
您可以在查询中使用“RETURNING”子句获取生成的键:
使用连接
当您需要执行顺序查询(没有事务)时,您可以创建新连接或从池中借用一个连接:
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 rows = ar2.result(); } }); } });
注意
|
准备好的查询缓存取决于setCachePreparedStatements 并且不依赖于您是创建准备好的查询还是使用direct prepared queries
|
PreparedQuery
可以执行有效的批处理:
游标和流媒体
默认情况下,准备好的查询执行会获取所有行,您可以使用a 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 rows = ar2.result(); // Check for more ? if (cursor.hasMore()) { // Repeat the process... } else { // No more rows - close the cursor cursor.close(); } } }); } });
PostreSQL在事务结束时销毁游标,因此游标API将在事务中使用,否则您可能会收到34000
PostgreSQL错误。
游标过早释放时应关闭:
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
)TINYINT(
java.lang.Byte
)SMALLINT(
java.lang.Short
)MEDIUMINT(
java.lang.Integer
)INT,INTEGER(
java.lang.Integer
)BIGINT(
java.lang.Long
)FLOAT(
java.lang.Float
)DOUBLE(
java.lang.Double
)NUMERIC(
io.vertx.sqlclient.data.Numeric
)日期(
java.time.LocalDate
)DATETIME(
java.time.LocalDateTime
)时间(
java.time.Duration
)TIMESTAMP(
java.time.LocalDateTime
)年(
java.lang.Short
)CHAR(
java.lang.String
)VARCHAR(
java.lang.String
)BINARY(
io.vertx.core.buffer.Buffer
)VARBINARY(
io.vertx.core.buffer.Buffer
)TINYBLOB(
io.vertx.core.buffer.Buffer
)TINYTEXT(
java.lang.String
)BLOB(
io.vertx.core.buffer.Buffer
)文字(
java.lang.String
)MEDIUMBLOB(
io.vertx.core.buffer.Buffer
)MEDIUMTEXT(
java.lang.String
)LONGBLOB(
io.vertx.core.buffer.Buffer
)LONGTEXT(
java.lang.String
)
元组解码在存储值时使用上述类型
处理BOOLEAN
在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 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()); } });
处理NUMERIC
该Numeric
Java类型用于表示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实用程序命令,我们为此提供支持。可以在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
。
MySQLConnectOptions authenticationOptions = new MySQLConnectOptions().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()); } });
转载于:https://www.cnblogs.com/endv/p/11257577.html
Reactive MySQL Client相关推荐
- Vert.x MySQL Client中文版
Reactive MySQL Client中文版 翻译: 白石(https://github.com/wjw465150/Vert.x-Core-Manual) Reactive MySQL Clie ...
- easy mysql_GitHub - aleafs/easymysql: mysql client in cluster, based on node-mysql
Click About easymysql 基于node-mysql 开发而来,提供一个简单.高可用的mysql连接基础库.主要特性如下: 支持query超时控制: 可控制的连接池支持,SQL总是尽可 ...
- MYSQL连接出现Auth,使用navicat连接 mysql时出现client does not support auth...upgrading Mysql Client...
问题报错:使用navicat时发现出现如下情况: 原因:发现是由于navicat版本的问题,出现连接失败的原因:mysql8 之前的版本中加密规则是mysql_native_password,而在my ...
- Client does not support authentication protocol requested by server; consider upgrading MySQL client
错误一 Communications link failure due to underlying exception 这说明客户端连接数据库失败,是网络都连不上,不是密码错误连不上,需要检查ip.p ...
- mysql client 使用_mysqlclient怎么使用
mysql client 怎么用 1.输入密码:****** 2.ues mysql;使用Mysql 3.show databases;显示数据库 4.use register;使用数据库名为regi ...
- mysql时出现client does not support auth...upgrading Mysql Client
使用navicat连接 mysql时出现client does not support auth...upgrading Mysql Client 问题报错:使用navicat时发现出现如下情况: 原 ...
- Clinet dose not support authentication protocol request by server ;consider upgrading MySQL client
最近在将mysql安装好之后,用navicate连接,发现一直都报错,系统重启了之后就这样,如下: Clinet dose not support authentication protocol re ...
- 专业mysql client配置
专业mysql client配置 专业化mysql client配置如下: [client] & [mysql] [client] port = 3306 socket = /tmp/mysq ...
- CSS-T | Mysql Client 任意文件读取攻击链拓展
作者:LoRexxar@知道创宇404实验室 & Dawu@知道创宇404实验室 原文地址:https://paper.seebug.org/1112/#_6 英文版本:https://pap ...
- 关于在linux终端下使用mysql Client
登陆mysql Client 在linux终端直接输 mysql -u root -p 回车 之后就可以输入密码 登陆了 创建新的mysql用户 出现如下问题 解释如下 原因是我是使用了新设的用户,所 ...
最新文章
- 电子电路基础复习 —— 电感
- C# 2018.9.17
- Unity中Oculus分屏相机和普通相机一键切换
- 拜托,别再问我什么是 B+ 树了
- robot连接mysql_Robotframework使用自写库连接mysql数据库
- Atitit 软件方法论法典概论 attilax著作 目录 1. 基本法通则总则	2 2. 流程方法	3 2.1. 工具链建设法	4 2.2. 代码编写法	4 2.3. 注释法	4 2.4. 文档法
- python交互式换行_如何在Python中进行换行(换行)?
- npm webstorm配置_怎样使用webstorm中配置nodejs环境及npm
- 计算机网络连接图标 红叉,Win10网络图标显示红叉叉 检测不到网卡驱动解决方案...
- 【编程算法】跳跃游戏ⅠⅡⅢ(Python解法)
- 【超超超easy】5分钟:自制酷炫猫咪词云图,会点鼠标即可。
- 猫哥教你写爬虫 049--完结撒花
- android销毁指定activity,Android - 销毁指定Activity
- bdd 启动 data processing进程报错 Can't locate LWP.pm in @INC
- 会计准则中借方与贷方如何理解分析
- RESTful 标准接口教程
- 《尚硅谷大数据Hadoop》教程
- javaIO流详解--读取,写入文件的所有类与方法
- OCR技术系列之一 字符识别技术总览
- Android 花里胡哨的加载Loading动画