Java 如何减少vert.x中样板代码的数量

Java 如何减少vert.x中样板代码的数量,java,reactive-programming,vert.x,event-driven,Java,Reactive Programming,Vert.x,Event Driven,我已经阅读了一些关于的教程,但我仍然不明白如何最大限度地减少重复代码 例如,我需要实现从数据库获取数据的RESTful服务。我为表准备了2个bean类(Customer、Administrator)并实现了服务类: 管理员服务.java: public void getAll(RoutingContext routingContext) { jdbc.getConnection(ar -> { SQLConnection connection = ar.result()

我已经阅读了一些关于的教程,但我仍然不明白如何最大限度地减少重复代码

例如,我需要实现从数据库获取数据的RESTful服务。我为表准备了2个bean类(Customer、Administrator)并实现了服务类:

管理员服务.java

public void getAll(RoutingContext routingContext) {
    jdbc.getConnection(ar -> {
      SQLConnection connection = ar.result();
      connection.query(Queries.SELECT_ALL_ADMINS, result -> {
        List<Administrator> admins = result.result().getRows().stream().map(Administrator::new).collect(Collectors.toList());
        routingContext.response()
          .putHeader("content-type", "application/json; charset=utf-8")
          .end(Json.encodePrettily(admins));
        connection.close();
      });
    });
  }

  public void getOneById(RoutingContext routingContext) {
    final String id = routingContext.request().getParam("id");
    if (id == null) {
      routingContext.response().setStatusCode(400).end();
    } else {
      jdbc.getConnection(ar -> {
        // Read the request's content and create an instance of Administrator.
        SQLConnection connection = ar.result();
        select(id, connection, Queries.SELECT_ONE_ADMIN_BY_ID, result -> {
          if (result.succeeded()) {
            routingContext.response()
              .setStatusCode(200)
              .putHeader("content-type", "application/json; charset=utf-8")
              .end(Json.encodePrettily(result.result()));
          } else {
            routingContext.response()
              .setStatusCode(404).end();
          }
          connection.close();
        });
      });
    }
  }
public void getAll(RoutingContext routingContext) {
    jdbc.getConnection(ar -> {
      SQLConnection connection = ar.result();
      connection.query(Queries.SELECT_ALL_CUSTOMERS, result -> {
        List<Customer> customers = result.result().getRows().stream().map(Customer::new).collect(Collectors.toList());
        routingContext.response()
          .putHeader("content-type", "application/json; charset=utf-8")
          .end(Json.encodePrettily(customers));
        connection.close();
      });
    });
  }


  public void getOneById(RoutingContext routingContext) {
    final String id = routingContext.request().getParam("id");
    if (id == null) {
      routingContext.response().setStatusCode(400).end();
    } else {
      jdbc.getConnection(ar -> {
        // Read the request's content and create an instance of Administrator.
        SQLConnection connection = ar.result();
        select(id, connection, Queries.SELECT_ONE_CUSTOMER_BY_ID, result -> {
          if (result.succeeded()) {
            routingContext.response()
              .setStatusCode(200)
              .putHeader("content-type", "application/json; charset=utf-8")
              .end(Json.encodePrettily(result.result()));
          } else {
            routingContext.response()
              .setStatusCode(404).end();
          }
          connection.close();
        });
      });
    }
  }
在每种方法中都会重复。一般来说,这些类之间的区别在于sql请求和bean类


你能分享一下你的例子吗,或者展示一下如何改变我的方法吗?

VertX不是一个框架,它让一些开发人员可以很容易地设计自己的结构,但对一些人来说,它变成了一场噩梦。您需要的是一个预先设计好的框架,它可以与路由器、控制器、数据库连接一起使用。显然,vertx不是这样的,它更像一个库,可以按您想要的方式扩展它

我在您的代码中看到,对于每个服务函数,您都获得了SQL连接。如果您使用过其他框架,比如Spring,那么使用DI已经可以使用该连接。 您需要实现DI,一些MVC设计,然后您的样板代码将被删除

我也做过类似的事情,只是为了MongoDB

这就是一个例子 1.首先部署垂直线 2.第二服务器注入路由器 请注意,在3.4(将于本周发布)中,有一个新的
.routingContext.response()
.putHeader("content-type", "application/json; charset=utf-8")
/**
* deploy verticle
*/ 
@PostConstruct
public void deployVerticle() {
    Vertx vertx = Vertx.vertx();
    log.info("deply vertx start...... ");
    vertx.deployVerticle(dbVerticle);
    DeploymentOptions options = new DeploymentOptions();
    options.setInstances(4);
    StaticServer.setApplicationContext(context);
    vertx.deployVerticle(StaticServer.class.getName(), options);
    log.info("deply vertx end...... ");
}
@Override
public void start() throws Exception {
    Map<String, Api> apis = applicationContext.getBeansOfType(Api.class);
    JavaConfig javaConfig = applicationContext.getBean(JavaConfig.class);
    Router router = Router.router(vertx);
    apis.forEach((k, v) -> RouterUtils.injectRouter(v, router));
    vertx.createHttpServer().requestHandler(router).listen(javaConfig.httpPort());
}
public static void injectRouter(Api api, Router router) {
        Map<Method, RequestMapping> annotatedMethods = MethodIntrospector.selectMethods(api.getClass(), (MetadataLookup<RequestMapping>) 
                method -> AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class));
        RequestMapping annotatedClass = api.getClass().getDeclaredAnnotation(RequestMapping.class);
        annotatedMethods.forEach((method, request) -> {
            Class<?>[] params = method.getParameterTypes();
            Assert.isAssignable(RoutingContext.class, params[0]);
            router.route(request.method(), annotatedClass.value() + request.path()).handler(context -> {
                try {
                    context.response().putHeader("content-type", "application/json; charset=utf-8");
                    method.invoke(api, context);
                } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                    log.error("e :", e.getCause());
                }
            });
        });
    }
@RequestMapping("/")
public void root(RoutingContext context) {
    JsonObject query = new JsonObject();
    query.put("sql", "select * from user where username = ?");
    query.put("params", (new JsonArray()).add("zhengfc"));
    context.vertx().eventBus().request("db.query", query, ar -> {
        if (ar.succeeded()) {
            context.response().end(ar.result().body().toString());
        } else {
            log.error("db.query failed: {}", ar.cause());
        }
    });
}