Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    442

    [Java+MySql] Evitare l'inserimento di dati duplicati.

    Vorrei impedire l'inserimento di categorie con lo stesso nome. Ho trovato che per MySql c'è la clausola UNIQUE che fa il lavoro sporco al posto mio. Problema: questa evenienza solleva un'eccezione mentre io vorrei solo che l'utente ricevesse un warning dandogli la possibilità di modificare la sua scelta.
    Ho provato a fare così:

    codice:
                int result=statement.executeUpdate();
                if (result==0) {
                    JOptionPane.showMessageDialog(avviso);
                }
    Ma ovviamente non va perché statement.executeUpdate() sollevando l'eccezione sql passa il controllo direttamente al catch perciò in caso di errore il ramo if non viene mai eseguito.
    Come ovviare a ciò?
    Grazie.

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da Jamie04 Visualizza il messaggio
    Ho trovato che per MySql c'è la clausola UNIQUE che fa il lavoro sporco al posto mio. Problema: questa evenienza solleva un'eccezione mentre io vorrei solo che l'utente ricevesse un warning dandogli la possibilità di modificare la sua scelta.
    Se sai quale è l'error code specifico di MySQL per questa violazione, puoi testarlo andando a vedere il vendor-code ( getErrorCode() ) dentro SQLException.
    Non è il massimo .... così si è "legati" a MySQL (un altro DBMS avrebbe presumibilmente un altro error code) ma magari a te va bene ed è il "male minore".
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    442
    Ho trovato che esiste una SQLIntegrityConstraintViolationException che farebbe proprio al caso mio, però il mio metodo trattando l'inserimento di dati nel db può sollevare anche altre eccezioni sql quindi non posso catturare solo questo tipo...

  4. #4
    Utente di HTML.it L'avatar di Alex'87
    Registrato dal
    Aug 2001
    residenza
    Verona
    Messaggi
    5,802
    Usare due (o più) catch?
    SpringSource Certified Spring Professional | Pivotal Certified Enterprise Integration Specialist
    Di questo libro e degli altri (blog personale di recensioni libri) | ​NO M.P. TECNICI

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    442
    Mi sembra di aver risolto, ditemi un po' che ne pensate. Questo è il metodo di inserimento:

    codice:
    public static void insertMenu(String field) {
    
            PreparedStatement statement = null;
    
            //verifico che l'utente non abbia inserito un campo vuoto
            try {
                if (field == null || field.isEmpty()) {
                    JOptionPane.showMessageDialog(bla1);
                    return;
                }
    
                //inserisco fisicamente nel db il nuovo menu
                statement = connection.prepareStatement("INSERT INTO Menu VALUES (NULL, ?)");
                statement.setString(1, field);
                result=statement.executeUpdate();
    
            //catturo le eccezioni e chiudo lo statement per liberare risorse
            } catch (SQLIntegrityConstraintViolationException ex) {
                JOptionPane.showMessageDialog(bla2);
            } catch (SQLException e) {
                JOptionPane.showMessageDialog(bla3);
                Logger.getLogger(DBConnection.class.getName()).log(Level.SEVERE, null, e);
            }
            finally {
                if (statement != null) {
                    try {
                        statement.close();
                    } catch (SQLException ex) {
                        Logger.getLogger(DBConnection.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        }
    Nell'azione del pulsante che gestisce il salvataggio (e quindi richiama il metodo di cui sopra) ho messo un
    if (DBConnection.result==1) allora fai quello che devi (per il momento solo attivare altri campi) altrimenti rimani come stai.
    result l'ho dichiarata public e static.

    EDIT: ho subito trovato l'inghippo, se faccio un inserimento che va a buon fine dopo non va più probabilmente per via del fatto che result rimane su 1... ho aggiunto quindi un result=0 prima di result=statement.executeUpdate();
    adesso mi sembra che va
    Ultima modifica di Jamie04; 21-03-2014 a 21:25

  6. #6
    Utente di HTML.it L'avatar di Alex'87
    Registrato dal
    Aug 2001
    residenza
    Verona
    Messaggi
    5,802
    Quote Originariamente inviata da Jamie04 Visualizza il messaggio
    result l'ho dichiarata public e static.


    Non usare variabili "globali" per queste cose, sfrutta il fatto che una funzione può restituire un valore di ritorno...
    Ultima modifica di Alex'87; 21-03-2014 a 21:32
    SpringSource Certified Spring Professional | Pivotal Certified Enterprise Integration Specialist
    Di questo libro e degli altri (blog personale di recensioni libri) | ​NO M.P. TECNICI

  7. #7
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da Jamie04 Visualizza il messaggio
    Ho trovato che esiste una SQLIntegrityConstraintViolationException
    Sì ma è solo da Java 6. Se non hai problemi/questioni di compatibilità pre-Java 6 ... ok.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    442
    ok ho modificato così il metodo:

    codice:
    public static int insertMenu(String field) {
            
            int result=0;
    
            PreparedStatement statement = null;
    
            //verifico che l'utente non abbia inserito un campo vuoto
            try {
                if (field == null || field.isEmpty()) {
                    JOptionPane.showMessageDialog(bla1);
                    return result;
                }
    
                //inserisco fisicamente nel db il nuovo menu
                statement = connection.prepareStatement("INSERT INTO Menu VALUES (NULL, ?)");
                statement.setString(1, field);
                
                result=statement.executeUpdate();
    
            //catturo le eccezioni e chiudo lo statement per liberare risorse
            } catch (SQLIntegrityConstraintViolationException ex) {
                JOptionPane.showMessageDialog(bla1);
            } catch (SQLException e) {
                JOptionPane.showMessageDialog(bla2);
                Logger.getLogger(DBConnection.class.getName()).log(Level.SEVERE, null, e);
            }
            finally {
                if (statement != null) {
                    try {
                        statement.close();
                    } catch (SQLException ex) {
                        Logger.getLogger(DBConnection.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
            return result;
        }
    evitando l'uso della variabile globale che tanto ti sconvolge
    Già che ci siamo, è giusto secondo te che un metodo di questo tipo sia static?

  9. #9
    Utente di HTML.it L'avatar di Alex'87
    Registrato dal
    Aug 2001
    residenza
    Verona
    Messaggi
    5,802
    Non è che mi sconvolge, si tratta proprio di cattiva programmazione. Non tanto lo static, che ha le sue buone ragioni di esistere, ma il campo public: MAI esporre all'esterno lo stato di un oggetto (esistono i setter e i getter per modificare/leggere un valore) in quanto lo esponi a modifiche potenzialmente inconsistenti.

    L'accesso ai dati andrebbe fatto attraverso un apposito DAO (magari definito in un'interfaccia, in modo che si possa cambiare l'implementazione senza toccare il client). Ad esempio:

    codice:
    public interface CustomDao<T> 
    {
      public void insertOne(T object);
      public T readOne(String key);
      public List<T> readAll();
    }
    
    public class JdbcCustomDaoImpl implements CustomDao<Pippo>
    {
      private Connection connection = ...
    
      public void insertOne(Pippo pippo) { codice per inserito pippo a DB  }
      public Pippo readOne(String key) { fa una query e restituisce l'oggetto puntato da key }
      public List<Pippo> readAll() { query per restituire tutti i pippi del DB }
    }
    Poi lo utilizzerai così:

    codice:
    CustomDao myDao = new JdbcCustomDaoImpl();
    myDao.set...(...);
    
    myDao.insertOne(new Pippo("pippo1"));
    myDao.insertOne(new Pippo("pippo2"));
    
    Pippo pippo1 = myDao.readOne("pippo1");
    
    List<Pippo> pippi = myDao.readAll();
    SpringSource Certified Spring Professional | Pivotal Certified Enterprise Integration Specialist
    Di questo libro e degli altri (blog personale di recensioni libri) | ​NO M.P. TECNICI

  10. #10
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    442
    Grazie, ma questi concetti (che conosco solo in parte) sono un po' troppo sofisticati per questo progetto, li riservo a più avanti (quando dovrò fare progetti ben più complessi -sigh-).
    So che si potrebbe strutturare molto meglio di come ho fatto finora, ma credimi se ti dico che ho già fatto un bel passo avanti...
    Una domanda al volo che non c'entra molto ma per la quale non credo valga la pena aprire un nuovo topic: a cosa servono (in NB) le librerie Eclipse Link JPA 2.1 ? Ho visto per caso che fanno parte della mia applicazione, ho provato a toglierle ma se creo il jar non funziona più (mi dice che non trova la main class).
    Altra cosa bizzarra il jar su ubuntu posso lanciarlo solo da riga di comando con java -jar nomeapp.jar perché se provo a farlo direttamente da interfaccia grafica (facendo "open with Oracle java7 runtime") mi dice che non ha trovato il file properties (quello con le impostazioni per accedere al db). Sotto win questo non succede, e funziona!!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.