Utilizzo della INSERT sul DB

di il
9 risposte

Utilizzo della INSERT sul DB

Ciao a tutti,

Vorrei un suggerimento, allora di solito carico i dati sul database in questo modo:

PreparedStatement prep = con.prepareStatement("INSERT INTO TABELLA(NOME, COGNOME) VALUES ( ?, ?)");
            prep.setString(1, nome);
            prep.setString(2, cognome);
            prep.executeUpdate();
Vorrei un modo per evitare di indicare un indice di riferimento dei dati, cioè vorrei inviare i dati al preparedStatement in modo disordinato
senza indice, vorrei inviare i dati e poi sarà l' API a settare i campi corretti, mi servirebbe una cosa del tipo (notare che ho invertito il cognome con il nome, invio prima il cognome, e l'Api dovrebbe inserirlo al secondo campo)

PreparedStatement prep = con.prepareStatement("INSERT INTO TABELLA(NOME, COGNOME) VALUES ( ?, ?)");
            prep.setString(COGNOME, cognome);
            prep.setString(NOME, nome);
            prep.executeUpdate();

9 Risposte

  • Re: Utilizzo della INSERT sul DB

    manuel__89 ha scritto:


    Vorrei un modo per evitare di indicare un indice di riferimento dei dati, cioè vorrei inviare i dati al preparedStatement in modo disordinato
    Un indice lo DEVI comunque specificare, la API di PreparedStatement funziona solo con indici. Non necessariamente però devi fare i setXYZ con gli indici "in sequenza" ascendente.

    Insomma, che tu faccia

    prep.setString(1, nome);
    prep.setString(2, cognome);

    oppure

    prep.setString(2, cognome);
    prep.setString(1, nome);

    per il PreparedStatement è assolutamente indifferente. La cosa IMPORTANTE è che ad un indice corrisponda un "marker" nel SQL. Lo dice chiaramente anche il javadoc: SQLException - if parameterIndex does not correspond to a parameter marker in the SQL statement


    Poi se tu non vuoi mettere lì in quel punto direttamente delle costanti numeriche ma vuoi mettere dei nomi di costanti letterali ... sei liberissimo di farlo, non è quello un problema.

    Es.

    public static final int COGNOME_IDX = 2;

    Ma di più (o di diverso) non vedo cosa tu possa fare ...
  • Re: Utilizzo della INSERT sul DB

    Invece che tu sappi c'è un altro modo diverso al preparedStatement che lo possa permettere ?

    Io ho trovato questo, ma fa la SELECT, io ho bisogno di INSERT, e poi non è spiegato bene, per esempio c'è scritto dataSource e non so cosa sia
    
    NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
            MapSqlParameterSource paramSource = new MapSqlParameterSource();
            paramSource.addValue("name", name);
            paramSource.addValue("city", city);
            jdbcTemplate.queryForRowSet("SELECT * FROM customers WHERE name = :name AND city = :city", paramSource);
            
  • Re: Utilizzo della INSERT sul DB

    manuel__89 ha scritto:


    Invece che tu sappi c'è un altro modo diverso al preparedStatement che lo possa permettere ?
    Che possa permettere ... cosa? Di NON usare indici? (ma altro)
    Esistono svariate librerie/framework al di sopra di JDBC.

    manuel__89 ha scritto:


    Io ho trovato questo, ma fa la SELECT, io ho bisogno di INSERT, e poi non è spiegato bene, per esempio c'è scritto dataSource e non so cosa sia
    
    NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
            MapSqlParameterSource paramSource = new MapSqlParameterSource();
            paramSource.addValue("name", name);
            paramSource.addValue("city", city);
            jdbcTemplate.queryForRowSet("SELECT * FROM customers WHERE name = :name AND city = :city", paramSource);
            
    Questo è di Spring Framework. I template JDBC di Spring sono un leggero strato al di sopra di JDBC nudo e crudo. Ed è ovviamente anche possibile fare query di insert/update/delete. Ma è un'altra cosa ovviamente. Se non conosci i datasource e la tua applicazione non usa neanche Spring, chiaramente questo non ti serve.
  • Re: Utilizzo della INSERT sul DB

    Non e' difficile implementare un wrapper per le classi java.sql.* che supportino la possibilita' di passare parametri per nome invece che per posizione.

    la sintassi potrebbe essere: "SELECT .. FROM ... WHERE c1 = ?p1 AND c2 > ?p2"

    quindi si deve assegnare le posizioni a p1 e p2 (in questo caso 1 e 2) e quando si assegna al parametro "p1", l'assegnamento viene convertito in un assegnamento al parametro in posizione 1.

    Se si e' smaliziati, un paio d'ore di lavoro (esperienza personale)

    E visto che si e', si puo' anche migliorare la gestione delle eccezioni: ma che senso ha ricevere un'eccezione del tipo "Tabella non esistente" SE NON MI DICI QUALE TABELLA? Oppure: sintassi dello statement errata SE NON MI DICI QUALE STATEMENT E' SBAGLIATO?????
  • Re: Utilizzo della INSERT sul DB

    E quindi ... nulla da fare, visto che non ho molta esperienza
  • Re: Utilizzo della INSERT sul DB

    manuel__89 ha scritto:


    E quindi ... nulla da fare, visto che non ho molta esperienza
    Allora non ti proporrei nemmeno di usare cose tipo iBATIS/MyBatis che non sono degli ORM (come Hibernate) ma sono comunque ad un livello un po' superiore rispetto all'uso di JDBC puro.

    Scusa ma quindi quale è il problema o dubbio? Il minimo che potresti fare per rendere il codice un po' "pulito" è usare delle costanti letterali così:
    public class XYZ {
        private static final String INSERT_TABELLA_SQL = "INSERT INTO TABELLA (NOME, COGNOME) VALUES (?, ?)";
        private static final int INSERT_TABELLA_NOME_IDX = 1;
        private static final int INSERT_TABELLA_COGNOME_IDX = 2;
        
         ......
    E poi le usi così:
    PreparedStatement prep = con.prepareStatement(INSERT_TABELLA_SQL);
    prep.setString(INSERT_TABELLA_NOME_IDX, nome);
    prep.setString(INSERT_TABELLA_COGNOME_IDX, cognome);
    prep.executeUpdate();
  • Re: Utilizzo della INSERT sul DB

    Grazie infatti il codice è più pulito, io lo avevo fatto un po casareccio.

    Il problema è che vorrei evitare di utilizzare gli indici, ad esempio
    
    PreparedStatement prep = con.prepareStatement("INSERT INTO TABELLA(NOME, COGNOME)");
                prep.setString(COGNOME, cognome);
                prep.setString(NOME, nome);
                prep.executeUpdate();
    
    Questo è quello che vorrei fare, il preparedStatement dovrebbe riconoscere il nome del campo, senza indici
    Esiste qualcosa del genere ?
  • Re: Utilizzo della INSERT sul DB

    manuel__89 ha scritto:


    PreparedStatement prep = con.prepareStatement("INSERT INTO TABELLA(NOME, COGNOME)");
    Questo è quello che vorrei fare, il preparedStatement dovrebbe riconoscere il nome del campo, senza indici
    Esiste qualcosa del genere ?
    No non esiste così .... semplicemente perché quello NON è SQL corretto! (non ha senso e non funzionerebbe nemmeno)

    JDBC e in questo caso specifico PreparedStatement RICHIEDE di usare i placeholder (i "marker") ? e RICHIEDE l'uso degli indici. Stop. Punto.
    Se vuoi qualcosa di più, ad esempio poter fare es:

    "select count(*) from Xyz where first_name = :first_name"

    (nota il :first_name, questa è la named parameter notation usata dal NamedParameterJdbcTemplate)

    allora o usi Spring Framework e i suoi template JDBC, o usi un'altra libreria/framework (es. MyBatis) oppure lo strato al di sopra di JDBC te lo scrivi tu, se lo sai fare chiaramente.
  • Re: Utilizzo della INSERT sul DB

    Grazie mi stai insegnando un sacco di cose.
    Adesso è chiaro, non posso farlo
Devi accedere o registrarti per scrivere nel forum
9 risposte