Vert.x: 从数据库中检索记录
Vert.x: retrieve records from database
我有一个名为 selectAll
的方法,它必须 return 从数据库中选择的记录,但是当我想 return 它们作为字符串时,它不允许它并给我:
Local variable S defined in an enclosing scope must be final or effectively final.
我尝试将 final 添加到我的字符串中,但它仍然是一样的。
这是我的 selectAll()
方法:
public String selectAll(String table, String order) {
String S;
S = "";
this.getCnx().getConnection(res -> {
if (res.succeeded()) {
SQLConnection connection = res.result();
connection.queryWithParams(ReqSql.SELECT_ALL, new JsonArray().add(table).add(order), (ar) -> {
if (ar.failed()) {
this.sendError(500, response);
} else {
JsonArray arr = new JsonArray();
ar.result().getRows().forEach(arr::add);
S = ar.result().getRows().toString();
response.putHeader("content-type", "application/json").end(arr.encode());
}
});
}
});
}
public AsyncSQLClient getCnx(){
JsonObject mySQLClientConfig = new JsonObject()
.put("host", "localhost")
.put("database", "test")
.put("username", "test")
.put("password", "test")
.put("port", 3306);
return MySQLClient.createShared(vertx, mySQLClientConfig);
}
然后我为我的请求创建了另一个 class:
public class ReqSql {
public static final String SELECT_ALL = "SELECT * FROM ? ORDER BY ? ASC";
}
此致。
问题是如果要在 Lambda 表达式中使用它们,则需要将局部变量声明为 final
。但是您不能为最终变量赋值。所以这行不通:
final String S = "";
this.getCnx().getConnection(res -> {
//...
S = ar.result().getRows().toString();
//...
});
Vert.x 是高度异步的。这意味着大多数操作,如 getConnection()
,将立即感染 return,但它们的结果,在这种情况下 SQLConnection
,将在稍后的时间点可供 Handler
使用.
如果您尝试在主程序流中提供异步结果,那是行不通的。你想用 S
做什么可能是错误的。因此,如果您之后不需要 S
,我会将 S
转换为局部变量。
我建议您在 documentation 中阅读有关 Future
的内容。 Future
是异步调用结果的占位符。 Vert.x 充满了异步调用。使用 Future
你可以这样做:
Future<SQLConnection> connection = Future.future();
this.getCnx().getConnection(res -> {
if (res.succeeded()) {
logger.info("Got a connection.");
connection.complete(res.result());
} else {
connection.fail(res.cause());
}
});
您在 Future
上指定 Handler
以比 callbacks/Lambdas:
更易读的方式检索异步结果
connection.setHandler(res -> {
...
})
我有一个名为 selectAll
的方法,它必须 return 从数据库中选择的记录,但是当我想 return 它们作为字符串时,它不允许它并给我:
Local variable S defined in an enclosing scope must be final or effectively final.
我尝试将 final 添加到我的字符串中,但它仍然是一样的。
这是我的 selectAll()
方法:
public String selectAll(String table, String order) {
String S;
S = "";
this.getCnx().getConnection(res -> {
if (res.succeeded()) {
SQLConnection connection = res.result();
connection.queryWithParams(ReqSql.SELECT_ALL, new JsonArray().add(table).add(order), (ar) -> {
if (ar.failed()) {
this.sendError(500, response);
} else {
JsonArray arr = new JsonArray();
ar.result().getRows().forEach(arr::add);
S = ar.result().getRows().toString();
response.putHeader("content-type", "application/json").end(arr.encode());
}
});
}
});
}
public AsyncSQLClient getCnx(){
JsonObject mySQLClientConfig = new JsonObject()
.put("host", "localhost")
.put("database", "test")
.put("username", "test")
.put("password", "test")
.put("port", 3306);
return MySQLClient.createShared(vertx, mySQLClientConfig);
}
然后我为我的请求创建了另一个 class:
public class ReqSql {
public static final String SELECT_ALL = "SELECT * FROM ? ORDER BY ? ASC";
}
此致。
问题是如果要在 Lambda 表达式中使用它们,则需要将局部变量声明为 final
。但是您不能为最终变量赋值。所以这行不通:
final String S = "";
this.getCnx().getConnection(res -> {
//...
S = ar.result().getRows().toString();
//...
});
Vert.x 是高度异步的。这意味着大多数操作,如 getConnection()
,将立即感染 return,但它们的结果,在这种情况下 SQLConnection
,将在稍后的时间点可供 Handler
使用.
如果您尝试在主程序流中提供异步结果,那是行不通的。你想用 S
做什么可能是错误的。因此,如果您之后不需要 S
,我会将 S
转换为局部变量。
我建议您在 documentation 中阅读有关 Future
的内容。 Future
是异步调用结果的占位符。 Vert.x 充满了异步调用。使用 Future
你可以这样做:
Future<SQLConnection> connection = Future.future();
this.getCnx().getConnection(res -> {
if (res.succeeded()) {
logger.info("Got a connection.");
connection.complete(res.result());
} else {
connection.fail(res.cause());
}
});
您在 Future
上指定 Handler
以比 callbacks/Lambdas:
connection.setHandler(res -> {
...
})