Come configurare più query con leggere differenze

0

Sto scrivendo una pagina che mostrerà i dati statistici dell'utente su alcuni dei nostri prodotti. Fondamentalmente l'utente può ottenere risultati tra un intervallo di tempo specifico e aggiungere anche altri dati da cercare.

Ad esempio, voglio prendere tutti i clic dell'utente tra il 5/5/16 e il 5/10/16 per il nostro prodotto. Quindi ho la possibilità di filtrare per IP, ID utente, client Web e livello di prodotto.

Il mio problema è che non voglio creare un metodo per ogni query, perché ciò risulterebbe in un metodo per ogni query senza un timestamp, quindi uno con un timestamp.

Ad esempio, ho bisogno di una query per ogni filtro. Quindi una query che ricerca per data e ora dove IP =?, E una query in cui non viene fornito il timestamp, solo l'IP.

Questo deve essere fatto in Java, quindi ogni volta che il parametro cambia i tipi di dati, ho bisogno di aggiungere la logica per una dichiarazione diversa. IP e User_ID sono int, mentre il livello del prodotto e i client web sono varchar.

Indipendentemente dal filtro, rimando i risultati di 4 query in base alle informazioni interne. Quindi avrei bisogno di 4 query per i filtri con solo un timestamp, quindi ho bisogno di 4 query per ogni filtro, poiché ho ottenuto 4 risultati per richiesta. In totale, ho bisogno di 16 query per i filtri e 4 per il timestamp. Di seguito è riportato un esempio di ciò che desidero evitare:

 public int getTotalClicks(Timestamp date_from_ts, Timestamp date_to_ts, String lookup_type, String lookup_data) {

    Connection conn = DMConnector.getDMConnection();
    int total_tests = 0;

    try {
        PreparedStatement statement = null;

        if (!lookup_type.equalsIgnoreCase("user_id") && (date_from_ts == null || date_to_ts == null)) {
            statement = conn.prepareStatement("SELECT count(insert_id) AS total FROM " +
                    "Click_Tracking WHERE " + lookup_type + " = ? AND ended_with_error = 'false'");

            statement.setInt(1, Integer.parseInt(lookup_data));

        } else if (lookup_type.equalsIgnoreCase("user_id")) {


            //statement.setString(1, lookup_data);
            //TODO Add a join statement to get the user_id lookup with date constraint
        } else {
            statement = conn.prepareStatement("SELECT count(insert_id) AS total FROM " +
                    "Click_Tracking WHERE "+ lookup_type + " = ? AND timestamp BETWEEN ? AND ? " +
                    "AND ended_with_error = 'false' ");

            statement.setInt(1, Integer.parseInt(lookup_data));
            statement.setTimestamp(2, date_from_ts);
            statement.setTimestamp(3, date_to_ts);
        }

        ResultSet res = statement.executeQuery();

        while (res.next()) {
            total_tests = res.getInt("total");
        }

        statement.close();
        conn.close();

        return total_tests;

    } catch (SQLException ex) {
        ex.printStackTrace();
        EmailUtility emailUtility = new EmailUtility();
        emailUtility.sendErrorEmail(ex.getMessage());
    }

    return total_tests;
}

Fondamentalmente lookup_type sarebbe uno dei quattro filtri, mentre lookup_data sarebbe il valore. Ad esempio, cercando per IP, lookup_type sarebbe IP mentre lookup_data sarebbe 192.168.0.0

Questo blocco di codice verrebbe replicato per ciascuno dei quattro risultati che devo restituire per richiesta. Quindi la quantità di metodi si somma. Dovrei semplicemente scrivere ogni metodo singolarmente o esiste un'idea "migliore pratica" che dovrei prendere in considerazione?

Grazie per l'aiuto!

    
posta Colby 23.05.2016 - 20:53
fonte

1 risposta

1

Una soluzione può essere eseguita in questo modo se il codice sarà abbastanza statico.

controlli ogni filtro (se esiste) e poi aggiungi l'istruzione

Segue lo pseudo codice

orig_sql = ' select ... from table where 1 = 1 ' // note space at end

if ( filter1 )

{

   filter1_sql = ' and filter1 = '%s' ; Put value of filter_1 in %s

   orig_sql = orig_sql + filter1_sql ;

}

if ( filter2 )

{

   filter2_sql = ' and filter_2 = %d' ; // Put value of filter_2 in %d

      orig_sql = orig_sql + filter2_sql 

}

Spero che questo abbia un senso. Puoi mettere i controlli per vedere se c'è almeno un filtro o il sql originale restituisce tutto.

    
risposta data 23.05.2016 - 21:47
fonte

Leggi altre domande sui tag