如何通过Vertx返回数据库查询结果?为何返回的结果列表总是null?
问题成因
你使用的是异步非阻塞的Vert.x数据库客户端,execute()方法执行后只会提交查询请求,不会等待数据库返回结果,主线程会直接执行后续的打印、返回逻辑。此时onSuccess回调还没有触发,列表还未被写入数据,所以你拿到的是空列表(你代码里已经初始化了ArrayList,实际是空集合而非null,应该是调用侧判断为空时误以为是null)。等数据库返回结果后才会执行onSuccess内的逻辑往列表添加元素,此时方法早已返回,自然拿不到正确结果。
解决方案
推荐适配Vert.x的异步编程模型,修改方法返回异步结果,不要强行编写同步逻辑:
方案1:异步返回(推荐)
修改方法返回Future<List<JsonObject>>,调用侧通过回调获取结果:
public Future<List<JsonObject>> getAll() { return this.connect() // 连接建立后执行查询 .compose(conn -> client.query("SELECT * FROM user").execute()) // 查询成功后转换结果格式 .map(rows -> { List<JsonObject> list = new ArrayList<>(); for (Row row : rows) { list.add(row.toJson()); } return list; }) // 打印异常信息 .onFailure(e -> System.out.println(e.getLocalizedMessage())); }
调用方式:
getAll().onSuccess(list -> { // 此处可拿到完整的查询结果 System.out.println(list); // 后续业务逻辑写在此处 }).onFailure(e -> { // 处理查询异常 });
方案2:同步阻塞获取(不推荐)
如果业务必须同步返回,可以用CountDownLatch等待异步回调执行完成,注意不要在Vert.x的事件循环线程调用该方法,会阻塞整个事件循环导致服务不可用:
public List<JsonObject> getAll() throws InterruptedException { List<JsonObject> listObject = new ArrayList<>(); CountDownLatch latch = new CountDownLatch(1); try { this.connect(); this.client.query("SELECT * FROM user") .execute() .onSuccess(ar -> { for (Row row : ar) { listObject.add(row.toJson()); } latch.countDown(); }) .onFailure(e -> { System.out.println(e.getLocalizedMessage()); latch.countDown(); }); } catch (Exception e) { System.out.println(e.getLocalizedMessage()); latch.countDown(); } // 阻塞等待查询完成 latch.await(); return listObject; }
内容的提问来源于stack exchange,提问作者Neo
相关产品推荐
相关产品推荐

