Vert.x是异步的。在Vert.x中执行数据库查询时,您显然正在传递回调。那么,它是异步的?:
conn.updateWithParams(<font>"insert into user (email, name, password) values (?, ?, ?)"</font><font>, params, (r) -> { <b>if</b> (r.succeeded()) { System.out.println(</font><font>"Ok!"</font><font>); } <b>else</b> { <b>if</b> (r.cause() instanceof MySQLException) { MySQLException cause = (MySQLException) r.cause(); <b>if</b> (cause.errorMessage().errorCode() == 1062) { </font><font><i>// Duplicate key, ignore</i></font><font> } } </font>
不完全对,看看queryWithParams 方法内部:
<b>public</b> SQLConnection queryWithParams(String sql, JsonArray params, Handler<AsyncResult<ResultSet>> resultHandler) { <b>new</b> JDBCQuery(vertx, helper, options, ctx, sql, params).execute(conn, statementsQueue, resultHandler); <b>return</b> <b>this</b>; }
JDBCQuery 是一个简单对象,有趣部分是execute()方法,进入AbstractJDBCAction看看这个方法:
<b>public</b> <b>void</b> execute(Connection conn, TaskQueue statementsQueue, Handler<AsyncResult<T>> resultHandler) { ctx.executeBlocking(future -> handle(conn, future), statementsQueue, resultHandler); }
注意到调用的executeBlocking方法名称,你可能疑惑ctx来自哪里,其实来自JDBCClientImpl:
<b>public</b> SQLClient getConnection(Handler<AsyncResult<SQLConnection>> handler) { Context ctx = vertx.getOrCreateContext(); getConnection(ctx, ar -> ctx.runOnContext(v -> handler.handle(ar))); <b>return</b> <b>this</b>; }
结论是,最后,常规的Vert.x JDBC客户端没有任何魔力。它使用了一个简单的数据源:默认情况下为C3P0,但如果您愿意,也可以使用Hikari。您可能希望将池大小设置得更大, 默认为15个连接 。
这种实现的主要目标很简单 - 不阻止事件循环(从不阻止事件循环)。对大多数用例来说,它实际上非常好。只是不要指望它会用JDBC做一些神奇的事情,就像让它无阻塞一样。