Come gestire in modo efficiente i dati correlati in MVC?

3

Parlando di MVC con servlet e JSP, in un contesto su prodotti e produttori, quando si interroga l'applicazione per un elenco di prodotti:

  • il servlet carica un elenco di prodotti dal database in un oggetto List (o simile);
  • il servlet imposta tale elenco come attributo della richiesta e inoltra la richiesta a un JSP;
  • il JSP recupera l'elenco dalla richiesta e ne visualizza i contenuti sulla pagina web.

Se quanto sopra è corretto, la mia domanda è: come carico i produttori di prodotti (supponiamo che ogni prodotto contenga l'id dei suoi produttori)?

Un approccio comune che ho visto è che quando il JSP scorre all'interno dell'oggetto lista, dopo aver mostrato ogni prodotto, viene chiamato un altro metodo di classe che finalmente esegue una query sul database.

Ci sono due cose che non mi piacciono su questo approccio:

  1. interrompe il pattern MVC;
  2. diverse query, solitamente separate, vengono eseguite sul database, potenzialmente caricando gli stessi dati (ad esempio quando due prodotti provengono dallo stesso produttore).

È sopra vero? Esistono approcci migliori per risolvere il problema?

Finora sto pensando di fare in modo che un servlet carichi i dati del produttore in un oggetto separato (ad esempio Map ) insieme ai prodotti List : entrambi gli oggetti sono impostati sulla richiesta e quindi il JSP può accedere sia durante il rendering della pagina.

Un inconveniente (potenzialmente pericoloso) di questa idea è che richiede più memoria per contenere tutte le informazioni; qualcos'altro?

    
posta watery 15.09.2014 - 20:19
fonte

2 risposte

1

puoi usare ORM (mappatura relazionale di oggetti) come JPA o Hibernate. quando si utilizza ORM nel modello, non è necessario interrogare nuovamente l'oggetto correlato perché ORM lo gestirà automaticamente. ad esempio:

definisce la tua classe del modello e la sua relazione:

class Product
{
    Manufacturer manufacturer;

    //setter and getter
}

class Manufacturer
{
    Long id;
    String name;

    //setter and getter
}

chiamando il modello nel metodo del controllore:

public Result showProductList()
{
   List<Product> products = ProductModel.get();
   return Result.ok().render("products", products);
}

e puoi chiamare il nome del produttore nel prodotto dal tuo modello di prodotto.

<c:forEach var="product" items="${products}">
    <option value ="10"><c:out value="${product.manufacturer.name}"/></option>
</c:forEach>

disclaimer: il codice di esempio sopra non è il codice reale. Voglio solo mostrare il quadro generale sull'uso dell'ORM nel tuo codice. utilizzando questo approccio non si romperà il modello di progettazione MVC (perché non è necessario interrogare nuovamente l'oggetto dalla propria vista)

    
risposta data 09.02.2015 - 04:47
fonte
0

Sembra che si desideri mappare le tabelle unite agli oggetti compositi.

Per questo compito è meglio utilizzare il framework ORM già menzionato (meglio con le specifiche JPA). La mappatura delle relazioni con gli oggetti compositi può essere eseguita in un round trip in ORM. ORM usando più modi per ottimizzare l'accesso ai dati. Ma devi imparare un quadro piuttosto complesso.

L'approccio comune menzionato con l'interrogazione al DB nel rendering di JSP può essere causato dall'utilizzo del caricamento lazy di ORM per gli oggetti associati. Gli oggetti associati scaricati vengono inizializzati come oggetti proxy (i proxy hanno la stessa interfaccia come oggetti target, ma senza valori). I proxy vengono sostituiti con oggetti reali dal database di query o dalla cache al momento del primo accesso.

Se vuoi creare un codice per la query one-round-trip, puoi utilizzare lo stesso approccio come usare i framework ORM:

public List<Product> getProducts(Connection con) {
    List<Product> result = new ArrayList<>;
    Statement stmt = null;
    try {
       stmt = con.createStatement();
       //only one query
       ResultSet rs = stmt.executeQuery("SELECT * FROM product p INNER JOIN manufacture m ON p.manufacture_id=m.id");
       while (rs.next()) {

           Product product = new Product();
           product.set...(rs.getType('column_of_product'))
           ...
           Manufacturer manufacturer = new Manufacturer();
           manufacturer.set...(rs.getType('column_of_manufacturer'))
           ...
           product.setManufacturer(manufacturer);

           result.add(product);
       }
   } catch (SQLException e) {
       JDBCTutorialUtilities.printSQLException(e);
   } finally {
       if (stmt != null) { stmt.close(); }
   }
   return result;
}
  • aggiungi 1. No, non si interrompe pattern MVC - Questo non ha nulla a che fare con il Approccio MVC
  • add 2. Sulla base di questo esempio si vede che non c'è bisogno di più query nel database. Duplicare i dati o consumare più memoria è per risparmiare tempo di elaborazione:)
risposta data 21.05.2016 - 06:22
fonte

Leggi altre domande sui tag