Java

di il
24 risposte

24 Risposte - Pagina 2

  • Re: Java

    andbin ha scritto:


    saraciao ha scritto:


    Contiene il prezzo, la descrizione la data della recensione
    Scusa ma fare un DESCRIBE [nometabella]
    è difficile?
    Hai già fatto almeno 1 volta una query "a mano" con un qualche tool per MySQL??
    Questo è importante da sapere fare ...

    saraciao ha scritto:


    DBconnection.getConnection() dovrebbe leggere la recensione, inserire recensioni e cancellarle
    Nooo. getConnection() dovrebbe SOLO fornire la Connection, NON sa nulla di recensioni, pippo, pluto, paperino, ecc...
    E l'unica cosa che non so, è come l'hai implementato. Perché un conto è se quel getConnection() fornisce una NUOVA Connection ad ogni invocazione ... un altro conto è se in DBconnection c'è un meccanismo banale di "caching" per cui RIusa la stessa Connection.
    Questo conta e "impatta" su tutti i metodi di query.

    saraciao ha scritto:


    Ma oltre alla where il resto è giusto?
    NO, come te lo devo dire?
    Ho riaggiustato non so se hai notato sopra e getConnection fornisce una nuova connessione ad ogni invocazione....So che chiedo tanto ma potresti aggiustare il mio codice così capisco gli errori...
  • Re: Java

    saraciao ha scritto:


    Ho riaggiustato non so se hai notato sopra e getConnection fornisce una nuova connessione ad ogni invocazione....So che chiedo tanto ma potresti aggiustare il mio codice così capisco gli errori...
    Non è questione di "aggiustare" il tuo codice ... hai fatto troppe sviste ed "erroracci".

    Fai un FROM Review poi più avanti un from recensione ... mica hai 2 tabelle, no? Perché me le chiami diversamente??
    Poi fai un insertReviews( User review) e gli passi un User (User COSA?) "utente"? E un utente ha un "prezzo"? E che c'entra con le recensioni?
    E il prezzo lo passi con setString? E poi fai un stm.setInt() (nota: un int!!!) di review.getdescrizione() cioè una descrizione??? Ma davvero?

    Programmare significa ANCHE saper scrivere le cose in modo molto preciso ed accurato. Il tuo codice è tutto tranne questo ....
    Per come hai scritto il codice, non ti compilerà né funzionerà mai nulla ...
  • Re: Java

    Guarda questo.

    PREMESSE:

    Il mio esempio sotto presume che:

    A) Ci sia una tabella chiamata recensioni con le colonne:
    - id (tipo numerico, es. INTEGER in MySQL)
    - descrizione (tipo stringa, es. VARCHAR(100) in MySQL; il length a tua scelta)
    - prezzo (tipo numerico decimale, es. DOUBLE in MySQL)
    - data (tipo data, es. DATE in MySQL)

    B) Ci sia una classe Java chiamata Recensione che "modella" la tabella, fatta (abbozzata) così:
    import java.sql.Date;
    
    public class Recensione {
        private int id;
        private String descrizione;
        private double prezzo;
        private Date data;
    
        // metodi getId() / setId()  .....
        // metodi getDescrizione() / setDescrizione()  .....
        // ... altri getter/setter nella forma tradizionale .....
    }
    C) Ci sia un metodo DBconnection.getConnection() che ad ogni richiesta crea una NUOVA Connection (da chiudere sempre, quindi).
    E che se getConnection() fallisce, esso lanci fuori un SQLException.



    Con queste premesse, allora:
    import java.sql.Connection;
    import java.sql.Date;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.List;
    
    public class DaoRecensioni {
        public List<Recensione> getRecensioni() throws SQLException {
            Connection conn = DBconnection.getConnection();
    
            try {
                Statement stmt = conn.createStatement();
    
                try {
                    ResultSet rs = stmt.executeQuery("SELECT * FROM recensioni");
    
                    try {
                        return extractRecensioni(rs);
                    } finally {
                        rs.close();
                    }
                } finally {
                    stmt.close();
                }
            } finally {
                conn.close();
            }
        }
    
        private List<Recensione> extractRecensioni(ResultSet rs) throws SQLException {
            List<Recensione> recensioni = new ArrayList<Recensione>();
    
            while (rs.next()) {
                recensioni.add(extractRecensione(rs));
            }
    
            return recensioni;
        }
    
        private Recensione extractRecensione(ResultSet rs) throws SQLException {
            Recensione recensione = new Recensione();
            recensione.setId(rs.getInt("id"));
            recensione.setDescrizione(rs.getString("descrizione"));
            recensione.setPrezzo(rs.getDouble("prezzo"));
            recensione.setData(rs.getDate("data"));
            return recensione;
        }
    }
    Il getRecensioni() è nella forma "classica"/tradizionale con i try-finally "annidati" per garantire TUTTI i close.
    Mentre i due extractRecensioni/extractRecensione servono solo per mettere a fattor comune la estrazione di N record e di 1 record. Potresti infatti avere più metodi (es. getRecensione(int id) oppure un getRecensioniPerAnno(int anno) ecc... che hanno bisogno di nuovo di quelle stesse "mappature". Questi due metodi non sono nulla di che ... semplicemente si tratta di "buon senso" nella programmazione per evitare ripetizioni.

    Da Java 7 è stato introdotto un costrutto chiamato try-with-resource che semplifica un po' la gestione di codice come quello con svariate risorse da "chiudere". Quindi da Java 7 il getRecensioni() si può anche riscrivere così:
        public List<Recensione> getRecensioni() throws SQLException {
            try (
                Connection conn = DBconnection.getConnection();
                Statement stmt = conn.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT * FROM recensioni");
            ) {
                return extractRecensioni(rs);
            }
        }
    In questo codice i close() dentro i giusti finally CI SONO ancora tutti. Semplicemente sono "nascosti" all'interno del costrutto try-with-resource che è fatto apposta per semplificare questo aspetto.
    Questo getRecensioni() è funzionalmente uguale al precedente. C'è una leggera differenza nel trattamento delle eccezioni ma dovresti leggere il Java Language Specification e te lo lascio come esercizio molto futuro ..

    L'unica questione un po' spinosa (ma in JDBC purtroppo è così) sono le date, in generale la gestione dei valori temporali. Nell'esempio ho usato java.sql.Date ma si possono fare altre scelte.


    Noti l'accuratezza di tutto quanto? Se non la noti, non so che farci e non saprei aiutarti molto oltre ....


    P.S: il codice NON ho modo/tempo di provarlo ma in linea di massima dovrebbe essere corretto.
  • Re: Java

    andbin ha scritto:


    Guarda questo.

    PREMESSE:

    Il mio esempio sotto presume che:

    A) Ci sia una tabella chiamata recensioni con le colonne:
    - id (tipo numerico, es. INTEGER in MySQL)
    - descrizione (tipo stringa, es. VARCHAR(100) in MySQL; il length a tua scelta)
    - prezzo (tipo numerico decimale, es. DOUBLE in MySQL)
    - data (tipo data, es. DATE in MySQL)

    B) Ci sia una classe Java chiamata Recensione che "modella" la tabella, fatta (abbozzata) così:
    import java.sql.Date;
    
    public class Recensione {
        private int id;
        private String descrizione;
        private double prezzo;
        private Date data;
    
        // metodi getId() / setId()  .....
        // metodi getDescrizione() / setDescrizione()  .....
        // ... altri getter/setter nella forma tradizionale .....
    }
    C) Ci sia un metodo DBconnection.getConnection() che ad ogni richiesta crea una NUOVA Connection (da chiudere sempre, quindi).
    E che se getConnection() fallisce, esso lanci fuori un SQLException.



    Con queste premesse, allora:
    import java.sql.Connection;
    import java.sql.Date;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.ArrayList;
    import java.util.List;
    
    public class DaoRecensioni {
        public List<Recensione> getRecensioni() throws SQLException {
            Connection conn = DBconnection.getConnection();
    
            try {
                Statement stmt = conn.createStatement();
    
                try {
                    ResultSet rs = stmt.executeQuery("SELECT * FROM recensioni");
    
                    try {
                        return extractRecensioni(rs);
                    } finally {
                        rs.close();
                    }
                } finally {
                    stmt.close();
                }
            } finally {
                conn.close();
            }
        }
    
        private List<Recensione> extractRecensioni(ResultSet rs) throws SQLException {
            List<Recensione> recensioni = new ArrayList<Recensione>();
    
            while (rs.next()) {
                recensioni.add(extractRecensione(rs));
            }
    
            return recensioni;
        }
    
        private Recensione extractRecensione(ResultSet rs) throws SQLException {
            Recensione recensione = new Recensione();
            recensione.setId(rs.getInt("id"));
            recensione.setDescrizione(rs.getString("descrizione"));
            recensione.setPrezzo(rs.getDouble("prezzo"));
            recensione.setData(rs.getDate("data"));
            return recensione;
        }
    }
    Il getRecensioni() è nella forma "classica"/tradizionale con i try-finally "annidati" per garantire TUTTI i close.
    Mentre i due extractRecensioni/extractRecensione servono solo per mettere a fattor comune la estrazione di N record e di 1 record. Potresti infatti avere più metodi (es. getRecensione(int id) oppure un getRecensioniPerAnno(int anno) ecc... che hanno bisogno di nuovo di quelle stesse "mappature". Questi due metodi non sono nulla di che ... semplicemente si tratta di "buon senso" nella programmazione per evitare ripetizioni.

    Da Java 7 è stato introdotto un costrutto chiamato try-with-resource che semplifica un po' la gestione di codice come quello con svariate risorse da "chiudere". Quindi da Java 7 il getRecensioni() si può anche riscrivere così:
        public List<Recensione> getRecensioni() throws SQLException {
            try (
                Connection conn = DBconnection.getConnection();
                Statement stmt = conn.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT * FROM recensioni");
            ) {
                return extractRecensioni(rs);
            }
        }
    In questo codice i close() dentro i giusti finally CI SONO ancora tutti. Semplicemente sono "nascosti" all'interno del costrutto try-with-resource che è fatto apposta per semplificare questo aspetto.
    Questo getRecensioni() è funzionalmente uguale al precedente. C'è una leggera differenza nel trattamento delle eccezioni ma dovresti leggere il Java Language Specification e te lo lascio come esercizio molto futuro ..

    L'unica questione un po' spinosa (ma in JDBC purtroppo è così) sono le date, in generale la gestione dei valori temporali. Nell'esempio ho usato java.sql.Date ma si possono fare altre scelte.


    Noti l'accuratezza di tutto quanto? Se non la noti, non so che farci e non saprei aiutarti molto oltre ....


    P.S: il codice NON ho modo/tempo di provarlo ma in linea di massima dovrebbe essere corretto.
    Va bene grazie...ma se voglio fare inserimento e cancellazione di recensioni posso farlo stesso li...con lo stesso metodo usato li fa te solo cambiando la query?

    [/code]
  • Re: Java

    @saraciao, NON riquotare TUTTO il post a cui rispondi:NON SERVE! E' gia' scritto!

    Per fare SI PUÒ FARE TUTTO!

    MA programmare vuol dire anche ORGANIZZARE il codice in unita' facilmente mantenibili e riutilizzabili.

    NON ESISTE un'unica regola: e' tutta questione di esperienza.

    Vedila in questo modo: sei una ragazza (spero, almeno dall'alias ) e ti devi vestire per uscire con il tuo ragazzo. Come ti vesti?
    Se sei una a cui piacciono i vestiti/borsette e le scarpe, non hai una sola scelta! DIPENDE!

    - da dove vai
    - se sei solo con lui o con altri amici
    - dal tempo
    - da che ora alla sera
    - dalle scarpe che userai
    - dalla borsetta che abbinerai
    - dall'umore del tuo ragazzo (magari la sera prima vete bisticciato)
    - da cosa piace a lui che tu indossi
    - e da un'infinita' di altri fattori... (e questi li conoscete solo voi. Nemmeno Freud ha capito come funziona la mente di una donna )

    Le scelte 'stilistiche/organizzative' di scrittura del codice sono infinite: DIPENDE...
  • Re: Java

    saraciao ha scritto:


    ma se voglio fare inserimento e cancellazione di recensioni posso farlo stesso li...con lo stesso metodo usato li fa te solo cambiando la query?
    No, dovrai fare ALTRI metodi. Che potranno anche essere abbastanza differenti come struttura.

    Es.

    public Recensione getRecensione(int id)

    public boolean deleteRecensione(int id)

    public void insertRecensione(Recensione recensione)

    ecc....

    In alcuni casi dovrai usare un PreparedStatement e in certi metodi potresti non aver nemmeno bisogno di gestire un ResultSet (il delete sicuramente).

    Io ti ho mostrato l'approccio giusto e "accurato" per farlo. Poi devi ragionare ed "applicarti" tu.
  • Re: Java

    andbin ha scritto:


    saraciao ha scritto:


    ma se voglio fare inserimento e cancellazione di recensioni posso farlo stesso li...con lo stesso metodo usato li fa te solo cambiando la query?
    No, dovrai fare ALTRI metodi. Che potranno anche essere abbastanza differenti come struttura.

    Es.

    public Recensione getRecensione(int id)

    public boolean deleteRecensione(int id)

    public void insertRecensione(Recensione recensione)

    ecc....

    In alcuni casi dovrai usare un PreparedStatement e in certi metodi potresti non aver nemmeno bisogno di gestire un ResultSet (il delete sicuramente).

    Io ti ho mostrato l'approccio giusto e "accurato" per farlo. Poi devi ragionare ed "applicarti" tu.
    
    
     public void insertRecensione( Recensione recensione) { //inserisci recensione 
      	  Connection conn = DBconnection.getConnection();
          try {
              PreparedStatement stm = conn.prepareStatement("INSERT INTO Recensione VALUES (?, ?, ?, ?,?)");
              stm.setString(1, recensione.getNome());
              stm.setString(2, recensione.getPrezzo());
              stm.setInt(3, recensione.getdescrizione());
              stm.setDate(4, recensione.getDataRecensione);
              stm.execute();
              stm.close();
          } catch (SQLException e) {
              System.out.println(e.getMessage());
          }
        } 
    
       public void DeleteRecensioni (int id) {
    	   Connection conn = DBconnection.getConnection();
    	      try {
    	          String query = ("delete from users where id = ?");
                  PreparedStatement pstmt = conn.prepareStatement(query);
                  pstmt.setInt(1, id);
                  pstmt.executeUpdate();
    	     
              } catch (SQLException e) {
                  System.out.println(e.getMessage());
              }
          }
    }
        
    
    
    per inserimento e la cancellazione e giusto cosi?
  • Re: Java

    saraciao ha scritto:


    per inserimento e la cancellazione e giusto cosi?
    Nì.

    1) Passi 5 "?" in VALUES (?, ?, ?, ?,?) ma poi setti solo 4 parametri

    2) stm.setString(2, recensione.getPrezzo());
    Hai veramente il prezzo come String? È discutibile, detto in generale, ma potrebbe anche essere accettato.

    3) stm.setInt(3, recensione.getdescrizione());
    Questo NO, l'ho già detto prima

    4) i close() vanno sempre fatti, serve il meccanismo del try-finally (o il try-with-resource).
    ANCHE della Connection, dato che hai precisato che il getConnection() fornisce sempre una NUOVA Connection.

    5) le eccezioni dovrebbero uscire dai metodi. Solo "stampare" un messaggio è POCO. Il chiamante non potrebbe sapere nulla dell'errore.
    Se vuoi stampare il messaggio della eccezione ok, è accettabile ma poi devi RI-lanciare fuori l'eccezione.

    6) "delete from users where id = ?"
    Che c'entra users ???


    Le vedi queste cose ... oppure no? Queste sono le cose a cui DEVI prestare attenzione.
  • Re: Java

    andbin ha scritto:


    saraciao ha scritto:


    per inserimento e la cancellazione e giusto cosi?
    Nì.

    1) Passi 5 "?" in VALUES (?, ?, ?, ?,?) ma poi setti solo 4 parametri

    2) stm.setString(2, recensione.getPrezzo());
    Hai veramente il prezzo come String? È discutibile, detto in generale, ma potrebbe anche essere accettato.

    3) stm.setInt(3, recensione.getdescrizione());
    Questo NO, l'ho già detto prima

    4) i close() vanno sempre fatti, serve il meccanismo del try-finally (o il try-with-resource).
    ANCHE della Connection, dato che hai precisato che il getConnection() fornisce sempre una NUOVA Connection.

    5) le eccezioni dovrebbero uscire dai metodi. Solo "stampare" un messaggio è POCO. Il chiamante non potrebbe sapere nulla dell'errore.
    Se vuoi stampare il messaggio della eccezione ok, è accettabile ma poi devi RI-lanciare fuori l'eccezione.

    6) "delete from users where id = ?"
    Che c'entra users ???


    Le vedi queste cose ... oppure no? Queste sono le cose a cui DEVI prestare attenzione.
    
    
    public void insertRecensione( Recensione recensione) { //inserisci recensione 
      	  Connection conn = DBconnection.getConnection();
          try {
              PreparedStatement stm = conn.prepareStatement("INSERT INTO Recensione VALUES (?, ?, ?, ?,?)");
              stm.setString(1, recensione.getNome());
              stm.setDouble (2, recensione.getPrezzo());
              stm.setInt(3, recensione.getdescrizione());
              stm.setDate(4, recensione.getDataRecensione);
              stm.setId(5, recensione.getId);
               try {
                  return Recensione(stm);  // servono per le estrazione di N record 
              } finally {
                  stm.close();
              }
          }
               finally {
          conn.close();
      }
    }
     
    cosi giusto?
    mentre per delete va bene?
  • Re: Java

    saraciao ha scritto:


    cosi giusto?
    mentre per delete va bene?
    NO.

    Oltretutto c'è una questione di fondo che non hai nemmeno considerato. Quando si fa un "insert" un ID numerico come quello NON lo devi inserire tu. Lo deve generare il database. Nel caso del MySQL vuol dire che la colonna "id" dovrebbe essere AUTO_INCREMENT.

    E lato Java, dopo la esecuzione dell'insert, c'è il modo per prendere questo ID che poi tipicamente o lo si restituisce come valore di ritorno del metodo oppure lo si setta nell'oggetto ricevuto in argomento, così che il chiamante abbia l'oggetto "completo" e aggiornato.

    Inoltre, return Recensione(stm); NON ha alcun senso (il metodo è void, oltretutto). E comunque la classe Recensione non dovrebbe di certo ricevere qualcosa di JDBC.
Devi accedere o registrarti per scrivere nel forum
24 risposte