Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    [Vert.x] JSON complesso da subquery

    ciao!

    cerco si spiegarvi il problema con un esempio semplice.
    quindi non ho messo i vari controlli su eventuali errori, perchè so che in questo caso errori di connessione non ci stanno, ecc...

    sostanzialmente dovrei ottenere un json del genere da un db, collegandomi con vertx.:
    codice:
    {
        "data": [
            {
                "nome": "Dance",
                "canzoni": [
                    {
                        "titolo": "titolo1"
                    },
                    {
                        "titolo": "titolo1"
                    }
                ]
            },
            {
                "nome": "Straniera",
                "canzoni": [
                    {
                        "titolo": "titolo3"
                    },
                    {
                        "titolo": "titolo4"
                    }
                ]
            }
        ]
    }
    al momento ottengo questo:
    codice:
    {
        "data": [
            {
                "nome": "Dance",
                "canzoni": null
            },
            {
                "nome": "Straniera",
                "canzoni": null
            }
        ]
    }
    il mio codice è questo:
    codice:
    package com.vertx.test_vertx;
    
    
    import io.vertx.core.AbstractVerticle;
    import io.vertx.core.Promise;
    import io.vertx.core.http.HttpServerResponse;
    import io.vertx.core.json.Json;
    import io.vertx.core.json.JsonObject;
    import io.vertx.ext.web.Router;
    import io.vertx.mysqlclient.MySQLConnectOptions;
    import io.vertx.mysqlclient.MySQLPool;
    import io.vertx.sqlclient.PoolOptions;
    import io.vertx.sqlclient.Row;
    import io.vertx.sqlclient.RowSet;
    
    
    import java.util.ArrayList;
    import java.util.List;
    
    
    public class MainVerticle extends AbstractVerticle {
    
    
      private MySQLPool getClient() {
        MySQLConnectOptions connectOptions = new MySQLConnectOptions()
          .................;
    
    
        PoolOptions poolOptions = new PoolOptions().setMaxSize(5);
        return MySQLPool.pool(vertx, connectOptions, poolOptions);
      }
    
    
      @Override
      public void start(Promise<Void> startPromise) {
        Router router = Router.router(vertx);
    
    
        router.route("/").handler(routingContext -> {
          HttpServerResponse response = routingContext.response();
    
    
          getClient()
            .query("SELECT DISTINCT canzone_genere AS nome FROM canzoni")
            .execute(ar -> {
              RowSet<Row> rowSet = ar.result();
              List<Genere> list = new ArrayList<>();
    
    
              for (Row row : rowSet) {
                JsonObject jsonObject = row.toJson();
                Genere genere = jsonObject.mapTo(Genere.class);
    
    
                getClient()
                  .query("SELECT canzone_titolo AS titolo FROM canzoni WHERE canzone_genere = '" + genere.nome + "'")
                  .execute(ar2 -> {
                    RowSet<Row> rowSet2 = ar2.result();
                    List<Canzone> list2 = new ArrayList<>();
    
    
                    for (Row row2 : rowSet2) {
                      JsonObject jsonObject2 = row2.toJson();
                      Canzone canzone = jsonObject2.mapTo(Canzone.class);
                      list2.add(canzone);
    
    
                      genere.canzoni = list2;
                    }
                  });
    
    
                list.add(genere);
              }
    
    
              JsonObject jsonObject = new JsonObject();
              jsonObject.put("data", list);
    
    
              response
                .putHeader("content-type", "application/json; charset=utf-8")
                .end(Json.encodePrettily(jsonObject));
            });
        });
    
    
        vertx.createHttpServer()
          .requestHandler(router)
          .listen(8888, http -> {
            if (http.succeeded()) {
              startPromise.complete();
              System.out.println("In ascolto su http://localhost:8888/");
            } else {
              startPromise.fail(http.cause());
            }
          });
    
    
      }
    
    
    }
    vorrei capire due cose:
    1) se la strada che ho scelto per ottenere i vari "sotto-records" è corretta
    2) se si -> dove sbaglio?
    3) se no -> se per favore potete indicarmi una strada migliore!

  2. #2
    ho fatto qualche modifica.
    adesso il json risulta così:
    codice:
    {
      "data" : [ {
        "nome" : "Dance",
        "canzoni" : [ ]
      }, {
        "nome" : "Hardstyle",
        "canzoni" : [ ]
      }, {
        "nome" : "Italiana",
        "canzoni" : [ ]
      }, {
        "nome" : "ND",
        "canzoni" : [ ]
      }, {
        "nome" : "Straniera",
        "canzoni" : [ ]
      } ]
    }
    più corretto, nel senso che almeno risulta un array, ma cmq vuoto.
    questo il codice:
    codice:
        router.route("/").handler(routingContext -> {
          HttpServerResponse response = routingContext.response();
    
    
          getClient()
            .query("SELECT DISTINCT canzone_genere AS nome FROM canzoni ORDER BY canzone_genere")
            .execute(ar -> {
              RowSet<Row> rowSet = ar.result();
              List<Genere> list = new ArrayList<>();
    
    
              for (Row row : rowSet) {
                List<Canzone> list2 = new ArrayList<>();
                JsonObject jsonObject = row.toJson();
    
    
                Genere genere = new Genere();
                genere.setNome(jsonObject.getString("nome"));
    
    
                String query = String.format("SELECT canzone_titolo AS titolo FROM canzoni WHERE canzone_genere = '%s' ORDER BY canzone_titolo", genere.getNome());
    
    
                getClient()
                  .query(query)
                  .execute(ar2 -> {
                    RowSet<Row> rowSet2 = ar2.result();
    
    
                    for (Row row2 : rowSet2) {
                      JsonObject jsonObject2 = row2.toJson();
    
    
                      Canzone canzone = new Canzone();
                      canzone.setTitolo(jsonObject2.getString("titolo"));
    
    
                      list2.add(canzone);
                    }
    
    
                    // OK --> STAMPA LE CANZONI
                    for (Canzone c : list2) {
                      System.out.println(c.getTitolo());
                    }
                  });
    
    
                // KO --> NON STAMPA LE CANZONI
                for (Canzone c : list2) {
                  System.out.println(c.getTitolo());
                }
                genere.setCanzoni(list2);
    
    
                list.add(genere);
              }
    
    
              JsonObject jsonObject = new JsonObject();
              jsonObject.put("data", list);
    
    
              response
                .putHeader("content-type", "application/json; charset=utf-8")
                .end(Json.encodePrettily(jsonObject));
            });
        });
    vi ho messo due for.
    come vedete il secondo non stampa nulla, come si svuotasse appena uscito dall'execute.

  3. #3
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Il codice che va a riempire la lista canzoni è una lambda, quindi non è detto che venga eseguita PRIMA del ciclo for. Anzi, trattandosi di un'interazione col DB è molto probabile che venga eseguita dopo.
    O cambi approccio o dei prevedere un meccanismo di sincronizzazione tra la lambra e il codice che deve essere eseguito dopo.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  4. #4
    Quote Originariamente inviata da LeleFT Visualizza il messaggio
    Il codice che va a riempire la lista canzoni è una lambda, quindi non è detto che venga eseguita PRIMA del ciclo for. Anzi, trattandosi di un'interazione col DB è molto probabile che venga eseguita dopo.
    O cambi approccio o dei prevedere un meccanismo di sincronizzazione tra la lambra e il codice che deve essere eseguito dopo.
    ciao!

    eh si ho capito che il problema era quello, e stavo cercando un meccanismo per bloccare il loop esterno.
    cioè, bloccherei il loop esterno per fargli eseguire la subquery, e poi farlo continuare.
    solo che non riesco a capire come fare sinceramente.

    ma volendo posso anche cambiare approccio, solo che l'unica cosa che mi viene in mente è di eseguire le query con il classico jdbc come ho sempre fatto.

  5. #5
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Io non conosco Vert.x, ma dalla documentazione vedo che il metodo execute() restituisce un Future.
    Quindi puoi utilizzare il get() per ottenere il valore della sua computazione. Il metodo get() mette in attesa il codice fino al completamento dell'elaborazione del Future.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  6. #6
    Quote Originariamente inviata da LeleFT Visualizza il messaggio
    Io non conosco Vert.x, ma dalla documentazione vedo che il metodo execute() restituisce un Future.
    Quindi puoi utilizzare il get() per ottenere il valore della sua computazione. Il metodo get() mette in attesa il codice fino al completamento dell'elaborazione del Future.
    farò un tentativo!
    intanto grazie!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.