我有一个名为selectAll
的方法,它必须返回从数据库中选择的记录,但是当我想将它们作为String返回时,它不允许它并给我:
Local variable S defined in an enclosing scope must be final or effectively final.
我尝试将final添加到我的String中,但它仍然是相同的。
这是我的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);
}
我为我的请求创建了另一个类:
public class ReqSql {
public static final String SELECT_ALL = "SELECT * FROM ? ORDER BY ? ASC";
}
问候。
答案 0 :(得分:0)
问题是,如果要在Lambda表达式中使用局部变量,则需要将局部变量声明为final
。但是您无法为最终变量赋值。所以这不起作用:
final String S = "";
this.getCnx().getConnection(res -> {
//...
S = ar.result().getRows().toString();
//...
});
Vert.x是高度异步的。这意味着大多数操作(例如getConnection()
)会立即感染返回,但其结果(在本例中为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());
}
});
您在Handler
上指定Future
,以便以比回调/ Lambdas更可读的方式检索异步结果:
connection.setHandler(res -> {
...
})