Utilizzo di Map per passare i parametri di query in DAO

2

È molto comune vedere un'implementazione DAO di un generico come questa:

public List<E> getResultList(String namedQuery, Map<String, Object> parameters) {
    Query query = entityManager.createNamedQuery(namedQuery);
    parameters.entrySet().forEach(e -> query.setParameter(e.getKey(), e.getValue()));
    return query.getResultList();
}

Ho alcuni problemi con questo approccio:

  1. Utilizzare una struttura complessa per passare semplicemente un elenco di chiavi e amp; dati di valore.
  2. La creazione della mappa è molto dettagliata.

Esempio:

public List<TransacaoTEF> getActiveTransactions1(TipoMensagem tipoMensagem, LocalDate date) {
    Map<String, Object> parameters = new HashMap<>();
    parameters.put("type", tipoMensagem);
    parameters.put("date", date);
    return getResultList("namedQueryXTPO", parameters);
}

Per evitare ciò ho pensato di creare una semplice classe Parameter:

public List<E> getResultList(String namedQuery, Parameter... parameters) {
    Query query = entityManager.createNamedQuery(namedQuery);
    Arrays.stream(parameters).forEach(p -> query.setParameter(p.getName(), p.getValue()));
    return query.getResultList();
}

public List<E> getResultList(String namedQuery, List<Parameter> parameters) {
    Query query = entityManager.createNamedQuery(namedQuery);
    parameters.forEach(p -> query.setParameter(p.getName(), p.getValue()));
    return query.getResultList();
}   

Utilizzo:

public List<TransacaoTEF> getActiveTransactions2(TipoMensagem tipoMensagem, LocalDate date) {
    return getResultList("namedQueryXTPO", 
            new Parameter("type", tipoMensagem), new Parameter("date", date));
}

public List<TransacaoTEF> getActiveTransactions3(TipoMensagem tipoMensagem, LocalDate date) {
    List<Parameter> parameters = Arrays.asList(
            new Parameter("type", tipoMensagem), 
            new Parameter("date", date));
    return getResultList("namedQueryXTPO", parameters);
}   

È finita l'ingegneria o solo paranoia; p?

    
posta Rodrigo Menezes 22.01.2018 - 13:50
fonte

2 risposte

1

It's over engineering or just paranoia ;p ?

Non penso che sia neanche Sì, una mappa è una struttura di dati generica, ma è anche la prima cosa a cui ti rivolgi quando hai bisogno di coppie chiave-valore o valore-param. Quindi la maggior parte delle persone lo fa e poi il resto del codice è solo loro che sono responsabili e non fanno cose del genere:

Map<String, Object> parameters = new HashMap<>();
parameters.put(null, someValue);
parameters.put("%$@*^%", someOtherValue);

Se utilizzi una classe Parameter puoi fare qualcosa in più rispetto a ciò che ti offre una mappa. Puoi affermare o convalidare alcune delle cose che hai posto al suo interno, come non specificare un nome di parametro nullo come sopra, o forse non inviare valori di null ma un JDBC NULL invece, o qualsiasi altra cosa ...

Una mappa è solo un secchio. Quello che metti dentro è ciò che ottieni. Nulla di bello. Se la tua applicazione è semplice, pochi sviluppatori disciplinati, ecc, allora una mappa potrebbe essere sufficiente.

Se stai creando una biblioteca o se vuoi assicurarti che ci siano alcune sicurezze, allora una classe Parameter è migliore.

    
risposta data 23.01.2018 - 12:39
fonte
1

Per alleviare la noia della creazione della mappa, spesso scriverò un po 'di utilità: (codice skeleton)

Map addKeyValuePairs(Map m, Object...pairs) {
   // TODO test that pairs has an even number
  for (int i=0; i<pairs.length; i+=2) {
     // TODO Add null checks as desired
     m.put(pairs[i].toString(), pairs[I+1].toString());
  }
  return m;
}
    
risposta data 23.01.2018 - 17:33
fonte

Leggi altre domande sui tag