Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Aug 2007
    Messaggi
    41

    oggetto connessione a DB: quando crearlo?

    ho un DB e un'interfaccia java che ci "dialoga"...
    ho creato una classe "Connessione" dove ho messo due metodi static, uno void per il caricamento dei driver e uno che restituisce un oggetto connessione...
    ora mi chiedo: essendo la mia un'applicazione standalone, è meglio ogni volta che faccio una query o un update aprire la connessione (cioè creare in ogni frame un oggetto Connection conn e richiamare ove necessario conn = COnnessione.connetti() ) oppure cercare di creare un oggetto statico 'globale' da aprire e chiudere a piacimento (ma nel caso come si fa? nella classe Connessione non mi fa creare un oggetto static), oppure ancora aprire una volta (o una volta per tutte con l'oggetto static o una volta per frame) la connessione e poi richiuderla solo al termine del programma? Cioè quale tra queste cose è meglio per l'efficienza e la 'buona programmazione', considerando che l'applicazione è standalone e si connette a un DB residente?

    grazie!

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Conviene sempre aprire una sola volta la connessione al db e usare sempre quella per le query.
    Trovi un esempio nella mia pillola JDBC: qui.

    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it
    Registrato dal
    Aug 2007
    Messaggi
    41
    Originariamente inviato da LeleFT
    Conviene sempre aprire una sola volta la connessione al db e usare sempre quella per le query.
    Trovi un esempio nella mia pillola JDBC: qui.

    Ciao.
    Grazie mille Lele! effettivamente non l'avevo letta :-)

    ora ho qualche domanda più specifica da fare, dopo aver dato un'occhiata anche al codice di esempio nella tua pillola... tra l'altro uso proprio il connector-j per cui già le prime righe sono utili :-)

    1) prima di tutto vedo che dopo aver fatto la query tu chiudi anche il ResultSet e lo Statement: ma è necessario farlo?? credevo che si chiudessero da sé :-)

    2) la classe connetti() assegna l'oggetto connessione alla variabile db che hai messo private... come ci potrei accedere da altri file? cioè come si fa a richiamarla da altri frame? cioè in un file classe ho i metodi di connessione, in altri file.java ho l'interfaccia e i metodi per le query e gli update.

    per esemplificare riporto qui sotto il codice del mio file Connessione.java per come è scritto adesso:

    codice:
    import java.sql.*;
    
    
    public class Connessione {
        
        
        
        /** Creates a new instance of Connessione */
        public Connessione() {
           
        }
            
        public static void caricaDriver() {
            //carico i driver di mysql
                try {
                Class.forName("com.mysql.jdbc.Driver");
                }
                catch (Exception e){
                    System.err.println("Errore driver DB!");
                    System.err.println(e.getMessage());
                }
        }  
        
        public static Connection connetti() throws SQLException {
        //apro la connessione al DB
            return DriverManager.getConnection("jdbc:mysql://localhost:3306/miodatabase", "root", "");
        }
    }
    nel codice degli altri file che lo usano, uso queste righe di comando:
    una volta per frame, prima di connettermi:
    codice:
    Connessione.caricadriver();
    al momento delle querry, ho due versioni: una è priva di chiusura della connessione, attualmente! ed è questa:
    codice:
    Statement leggi = Connessione.connetti().createStatement();
    ResultSet rs = null;
    rs = executeQuery("stringa_sql");
    //ecc.
    l'altra versione, un tentativo, è:
    codice:
    Connection conn = Connessione.connetti();
    Statement leggi = conn.createStatement();
    ResultSet rs = null;
    rs = executeQuery("stringa_sql");
    //ecc.
    conn.close();
    (la parte e le variabili relative a nome database, password ecc non mi servono perché il db è unico e metto subito tutti i dati nella stringa di connessione vera e propria. anche il metodo isConnesso() si può saltare, perché mi basterebbe di sapere il risultato di connetti()... mi serve di capirlo per un progetto d'esame che comunque dovrà funzionare per pochi minuti.... nonsottilizzerei ;-) mi basta che sia corretto il concetto e che non dia errori ^^')

    scusatemi l'ignoranza: per dire a che livello sono con questa roba, avevo anche tenuto per un po' una bellissima Connessione.connetti().close() che ripensandoci penso che apriva una nuova connessione e la richiudeva subito (intelligentissimo!) :-)
    grazie!

  4. #4
    Utente di HTML.it
    Registrato dal
    Aug 2007
    Messaggi
    41
    in particolare mi preme il punto 2) .... grazie :-)

  5. #5
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Originariamente inviato da shirim
    1) prima di tutto vedo che dopo aver fatto la query tu chiudi anche il ResultSet e lo Statement: ma è necessario farlo?? credevo che si chiudessero da sé :-)
    Diciamo che in quello specifico caso la chiusura dello statement e del ResultSet non sono propriamente necessari in quanto quegli oggetti vengono automaticamente deallocati al termine del metodo. Ad ogni modo è sempre buona norma chiudere statement e resultset quando non sono più necessari.

    2) la classe connetti() assegna l'oggetto connessione alla variabile db che hai messo private... come ci potrei accedere da altri file? cioè come si fa a richiamarla da altri frame? cioè in un file classe ho i metodi di connessione, in altri file.java ho l'interfaccia e i metodi per le query e gli update.
    La variabile db è privata proprio per impedire all'esterno di raggiungerla: in quel modello non si deve mai fare riferimento a tale variabile poichè è ad uso esclusivo della classe. L'accesso ad essa avviene per mezzo dei metodi che la classe stessa mette a disposizione, questo significa che dall'esterno nessuna classe conosce l'esistenza della variabile db e non ha alcun senso che la conoscano. Tutto ciò che le altre classi debbono poter fare è "eseguire query di selezione" e "eseguire query di aggiornamento" sul DB. Quindi, per poter utilizzare il db da classi esterne, non devi fare altro che passare un riferimento all'oggetto Database dove questo serve.

    Ad esempio, nella classe principale, quella con il main, istanzi un oggetto di tipo Database:
    codice:
    ...
    public static void main(String [] srgs) {
       Database db = new Database(...);
    }
    Quindi, lo passi a tutte le finestre che dovranno accedere al database, magari nel costruttore:
    codice:
    Finestra1 f = new Finestra1( db );
    Finestra2 f2 = new Finestra2( db );
    A questo punto le due finestre avranno un riferimento al DB e lo potranno tranquillamente usare: in questo modo viene effettuata una sola connessione al DB, che tutte le finestre della tua applicazione potranno utilizzare.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  6. #6
    Utente di HTML.it
    Registrato dal
    Aug 2007
    Messaggi
    41
    (A.S: ho domani la consegna del progetto, per cui chi leggesse dopo, se vuole può ripondere comunque che è sempre interessante, ma non è più necessario né urgente, grazie :-) )


    ok, credo di aver capito :-), cioè applicato al mio codice: tengo la classe Connessione, creo un oggetto Connection nella classe Main (quella col main ;-) ), oppure nella prima classe che usa il db e lo inizializzo una volta tramite una chiamata
    Connection conn = Connessione.connetti();
    poi passo nel costruttore di tutte le finestre conn, in modo da renderlo sempre disponibile.
    In questo modo apro la connessione al db all'inizio dell'applicazione e la lasci oaperta per tutta la durata.

    Ora, per quanto riguarda la chiusura della connessione? Se infatti lascio sempre la connessione aperta, dovrò prevedere dei punti di chiusura, ma dato che le mie finestre non si susseguono necessariamente in un ordine dato (ho la possibilità di tornare indietro da alcune ad altre e tutte hanno un pulsante esci, ma possono essere chiuse anche con la 'x') non so a priori quale sarà l'ultima che uso... naturalmente nella gestione dell'evento del pulsante esci posso mettere
    conn.close();
    ma c'è modo di modificare (considerando anche che sono in Netbeans, ma questo si aggira) il comportamento dell'applicazione quando chiudo con la 'x'? So che c'è la possibilità di scrivere ON_EXIT.... ma si possono mettere più righe di comando come parametro? non so la sintassi, ma scrivere tipo ON_EXIT (dispose(), conn.close())?

    Infine, per quanto riguarda il caricamento dei driver, lo richiamo solo nella classe in cui effettuo la prima connessione, oppure devo lasciare il comando
    Connessione.caricaDriver();
    in tutte le finestre, oppure una volta caricati se non li scarichi restano lì anche cambiando finestra, oppure ancora c'è un modo anche in questo caso di fare un oggetto e passarlo alle finestre?

    Grazie ancora :-)

  7. #7
    Utente di HTML.it
    Registrato dal
    Aug 2007
    Messaggi
    41
    però un attimo.... :master:

    oltre quanto espresso nel messaggio precedente, ho un ultimo dubbio sulla connessione....
    la procedura di passare l'oggetto Connection da una finestra all'altra, infatti, non è proprio equivalente all'avere un oggetto statico (che comunque non ho ancora capito se si può fare oppure no ), perché è vero che la connessinoe resta sempre la stessa e quindi sempre aperta, ma è vero anche che ad ogni finestra si istanzia un nuovo oggetto Connection, al quale dovrò assegnare il valore dell'oggetto Connection passato....
    cioè se l'oggetto passato nel costruttore si chiama myconn, in ogni finestra dovrò scrivere
    Connection conn = myconn;
    quindi è reale il vantaggio rispetto a chiudere la connessione ogni volta e richiamare in ogni nuova finestra Connection conn = Connessione.connetti(); ?

    Perché se si potesse creare una variabile statica conn inizializzata a null all'interno della classe Connessione (ma fuori di ogni suo metodo), allora si potrebbe mettere all'interno di Connessione.connetti() un if che controlla se la variabile è null e se lo è gli assegna la connessione, se non lo è restituisce conn; poi potrei mettere all'interno di connetti() ugualmente un if che controlla se il driver è caricato (prima di fare la connessione) usando un'altra variabile stavolta Boolean driverCaricato sempre statica che se è a false richiama caricaDriver() e poi nella prima finestra in cui uso la connessione, allora richiamare una volta per tutte Connessione.connetti() senza pensare più ai driver e nelle altre finestre senza passare alcun parametro, mettere sempre solo un if di sicurezza che controlla se (conn == null), se lo è chiama Connessione.connetti() e se non lo è usa conn direttamente per creare gli Statement.

    Si potesse fare, concettualmente mi parrebbe meglio (me le sogno di notte queste cose, cioè le rumino prima di addormentarmi, ma poi non so se e come i possano realizzare! ^^'), però se vado a creare una variabile statica dove dico io mi dice illegal start su
    static Connection conn = null;
    mentre se invece creo il Boolean (che andrebbe bene uguale per lui) senza static cioè così:
    Boolean caricato = false;
    sempre nella stessa posizione, mi dice che non posso usare poi la variabile che non è statica in un contesto statico (cioè i metodi, che sono statici).

  8. #8
    Utente di HTML.it
    Registrato dal
    Aug 2007
    Messaggi
    41
    ok ragazzi ho risolto, era una stupidaggine :-)
    non usavo private/public prima di static, così funziona :-)

    comunque se avete commenti sul modo in cui ho condotto il ragionamento e sulla soluzione finale intervenite, perché penso che se mi confermate la correttezza (anche non in tempo per il mio esame non importa.... tanto a me funziona per cui mi piace anche di presentare una soluzione personale mia anche non fosse l'ideale) possa essere una discussione ineteressante per chi cerchi info del genere ^^

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.