Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Wind Tre 'accende' il 5G Standalone in Italia: si apre una nuova era basata sui servizi
Wind Tre 'accende' il 5G Standalone in Italia: si apre una nuova era basata sui servizi
Con la prima rete 5G Standalone attiva in Italia, WINDTRE compie un passo decisivo verso un modello di connettività intelligente che abilita scenari avanzati per imprese e pubbliche amministrazioni, trasformando la rete da infrastruttura a piattaforma per servizi a valore aggiunto
OPPO Find X9 Pro: il camera phone con teleobiettivo da 200MP e batteria da 7500 mAh
OPPO Find X9 Pro: il camera phone con teleobiettivo da 200MP e batteria da 7500 mAh
OPPO Find X9 Pro punta a diventare uno dei riferimenti assoluti nel segmento dei camera phone di fascia alta. Con un teleobiettivo Hasselblad da 200 MP, una batteria al silicio-carbonio da 7500 mAh e un display da 6,78 pollici con cornici ultra ridotte, il nuovo flagship non teme confronti con la concorrenza, e non solo nel comparto fotografico mobile. La dotazione tecnica include il processore MediaTek Dimensity 9500, certificazione IP69 e un sistema di ricarica rapida a 80W
DJI Romo, il robot aspirapolvere tutto trasparente
DJI Romo, il robot aspirapolvere tutto trasparente
Anche DJI entra nel panorama delle aziende che propongono una soluzione per la pulizia di casa, facendo leva sulla propria esperienza legata alla mappatura degli ambienti e all'evitamento di ostacoli maturata nel mondo dei droni. Romo è un robot preciso ed efficace, dal design decisamente originale e unico ma che richiede per questo un costo d'acquisto molto elevato
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 22-03-2006, 09:43   #1
carosene
Member
 
Iscritto dal: Jan 2004
Messaggi: 173
[Java] Struttura programma per accesso ad un DB

Sto realizzando un’applicazione che si connette ad un database Access ma ho i seguenti dubbi:

Immaginiamo di avere un oggetto persona, il quale incapsula i dati presenti in un record della tabella persone presente nel DB.
Questo oggetto mette a disposizione il metodo setAltezza(int altezza), chiaramente lo scopo di questo metodo è quello di aggiornare la tabella del DB.
A questo punto mi chiedo:

• Conviene aprire una connessione ogni volta che viene richiamato il metodo?
• Aprire la connessione nel costruttore e chiuderla nel metodo finalize()?
• Creare un oggetto che incapsuli una connessione, passandolo come parametro nel costruttore della classe Persona?
• È proprio l’idea della classe Persona che è concettualmente sbagliata? Creo
una classe per accedere al database e basta, rinunciando all’astrazione che permette la classe Persona?
• Ma quante connessioni è possibile avere in contemporanea con Access?
• Sto sbagliando tutto?

Chiaramente ho fatto i miei esperimenti usando il driver bridge JDBC-ODBC, ho notato che aprire e chiudere una connessione comporta dei malfunzionamenti senza alcuna eccezione. Tuttavia non so quanto sia conveniente tenere aperte molte connessioni.

Grazie in anticipo per ogni consiglio.
carosene è offline   Rispondi citando il messaggio o parte di esso
Old 22-03-2006, 16:53   #2
amedeoz
Junior Member
 
L'Avatar di amedeoz
 
Iscritto dal: Apr 2002
Messaggi: 10
Quote:
Conviene aprire una connessione ogni volta che viene richiamato il metodo?


Quote:
Aprire la connessione nel costruttore e chiuderla nel metodo finalize()?


Quote:
Creare un oggetto che incapsuli una connessione, passandolo come parametro nel costruttore della classe Persona?
Comincia ad andare meglio... al più l'oggetto Persona lo passi ad un metodo di tale classe che implementa la persistenza (cioè che provvederà, nel caso tuo ad aggiornare il record nel DB)

Quote:
È proprio l’idea della classe Persona che è concettualmente sbagliata?
Forse l'unica cosa corretta che hai pensato è stata quella di incapsulare un record del database con una classe Persona!!!

Quote:
Creo una classe per accedere al database e basta, rinunciando all’astrazione che permette la classe Persona?


Quote:
Ma quante connessioni è possibile avere in contemporanea con Access?
Direi che verso le 5 conenssioni in contemporanea rischi di fottere la base dati (access l'ho usato giusto un paio di volte e usavo un pool di connessioni di 5 con 2 in contemporanea)

Quote:
• Sto sbagliando tutto?
Ecco la prima cosa corretta ke hai detto!!!

Ovviamente il tutto è in tono molto ironico...
credo che ti convenga studiare bene la teoria della programmazione ad oggetti.
Ti studi qualche bel pattern...

Il consiglio che posso darti è di "dividere" i compiti alle singole classi...
La classe Persona incapsula i dati della persona e se gli attribuisci anche il compito della persistenza (come avviene negli Entity Bean ad esempio), la cosa si complica un po' per problemi di sincronizzazione, accesso concorrente e balle varie...
Ti fai una bella classettina che ti gestisce le connessioni (anche nn in pool) semplice semplice (apri, chiudi) e una bella classettina che esegue le singole operazioni (legge, inserisce, aggiorna, elimina)

Non è una soluzione elegante ma almeno hai diviso i compiti tra le varie classi

Spero di esserti stato utile...
amedeoz è offline   Rispondi citando il messaggio o parte di esso
Old 22-03-2006, 17:19   #3
sottovento
Senior Member
 
L'Avatar di sottovento
 
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
Ciao,
per prima cosa, fai qualche valutazione:
- Quanti e quali oggetti devono girare nel tuo applicativo (fai una stima di massima);
- Come interagiscono fra di loro (devi cercare di individuare quanti, fra di loro, vanno a "pestarsi i piedi" l'uno con l'altro per accedere al database);

Quando hai fatto queste valutazioni, potrai decidere piu' tranquillamente.
Ad ogni modo, le connessioni al database sono in numero piuttosto limitato, ed aprire una connessione e' un'operazione dispendiosa (in termini di tempo e di risorse di sistema).
Inoltre, piu' connessioni apri, piu' rischi di perderne a seguito, per esempio, di qualche bug nel software (li facciamo tutti,no?).

Personalmente non sono a favore della creazione di classi per incapsulare il lavoro fatto da Connessioni e Statement... naturalmente non conosco l'applicativo e ti prego di scusarmi se il commento e' fuori luogo, ma esperienza insegna che il 90% delle classi cosi' partorite finiscono solo con il limitare l'uso delle classi originali. Insomma, si scrive codice per limitarsi...

L'idea di aprire una connessione ad ogni chiamata di metodo (a meno che non chiami questo metodo raramente) non sembrerebbe vantaggiosa.
Il fatto di avere un oggetto Persona che gestisca anche il suo record nella tabella, invece, e' carina.
Fai solo attenzione al fatto che, quando l'applicazione cresce (e magari e' composta da parecchi thread) si potrebbero creare di problemi di consistenza (ovviamente dipende dalle operazioni che serve implementare).

High Flying
Sottovento
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 22-03-2006, 18:34   #4
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Credo che l'idea dell'oggetto Persona ed il problema che si è posto circa la sua persistenza dimostri come carosene abbia ben chiaro cosa sia l'orientamento agli oggetti (almeno per come lo vedo io).

L'uso del metodo finalize() per compiere operazioni di "pulizia" non è in sè errato ma occorre tener conto che esso è certamente efficace solo per gli oggetti che la JVM consideri "short-lived" (non sopravvivono ad un certo numero di puliture della regione di memoria dedicata ai nuovi arrivati). Quando un oggetto passa da short-lived a long-lived, la sua "finalizzazione" può diventare eventuale. La JVM può essere infatti impostata per espandere le dimensioni dell'heap fino al limite prima di liberare la memoria occupata dagli oggetti vegliardi ed è ben possibile che tale limite non sia mai raggiunto, cosa che rimanda la liberazione delle connessioni al momento dello spegnimento dolce (esaurimento dei Thread in esecuzione) della JVM. Se tale tipo di spegnimento non si verifichi, è inoltre possibile che la connessione sopravviva alla JVM.

Anche quella di creare un oggetto che incapsuli la base dati è un'intuizione molto "OO" e, più generale, ottima per quanto riguarda l'approccio alla scrittura di un'applicazione, se consideriamo "bene" isolare quelle inevitabili parti di un sistema che siano dipendenti da risorse esterne alla logica dell'applicazione.

Potremmo pensare ad una cosa del genere:

Codice:
public abstract class DBObject {
    private Database database = DBFactory.getDatabase(); //ipotesi

    public void set(DBObject who, Object field, Object newValue) {
        database.update(who, field, newValue);
    }

    public Object get(DBObject who, Object field) {
        return database.get(who, field);
    }
}

e poi:

Codice:
public class Persona extends DBObject {

    public void setAltezza(int altezza) {
        update(this, "altezza", altezza);
    }

    public int getAltezza() {
        return get(this, "altezza");
    }
}
Qui "Database" è l'ipotetica rappresentazione della base dati e DBFactory il creatore di questo Database. Ovviamente si tratta di null'altro che uno spostamento del problema delle connessioni. Tuttavia, propagando un oggetto che rappresenti il concetto di "database", sei libero di concentrare in un solo punto del sistema le tue decisioni in tema di gestione delle connessioni.

Puoi aprirne e chiuderne una ad ogni invocazione di update o get ma noterei come la presenza di un delegato alla gestione della persistenza delle "persone" favorisca l'ipotesi di una connessione unica.
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 22-03-2006, 19:05   #5
sottovento
Senior Member
 
L'Avatar di sottovento
 
Iscritto dal: Nov 2005
Città: Texas
Messaggi: 1722
Ciao,
penso che PGI-Bis abbia sintetizzato in maniera superlativa quanto c'era da dire sul problema.

Volevo solo aggiungere che, probabilmente, l'oggetto Persona avra' altri attributi e caratteristiche oltre a quelle di accedere ad un database.
Per questo motivo eviterei una struttura di specializzazione e mi rivolgerei verso un meccanismo di aggregazione.

Ovviamente l'ultima parola spetta a te, che conosci il problema.

High Flying
Sottovento
sottovento è offline   Rispondi citando il messaggio o parte di esso
Old 22-03-2006, 20:15   #6
SaintTDI
Senior Member
 
L'Avatar di SaintTDI
 
Iscritto dal: Jul 2004
Città: Roma
Messaggi: 2094
Quote:
Originariamente inviato da PGI-Bis
Credo che l'idea dell'oggetto Persona ed il problema che si è posto circa la sua persistenza dimostri come carosene abbia ben chiaro cosa sia l'orientamento agli oggetti (almeno per come lo vedo io).

L'uso del metodo finalize() per compiere operazioni di "pulizia" non è in sè errato ma occorre tener conto che esso è certamente efficace solo per gli oggetti che la JVM consideri "short-lived" (non sopravvivono ad un certo numero di puliture della regione di memoria dedicata ai nuovi arrivati). Quando un oggetto passa da short-lived a long-lived, la sua "finalizzazione" può diventare eventuale. La JVM può essere infatti impostata per espandere le dimensioni dell'heap fino al limite prima di liberare la memoria occupata dagli oggetti vegliardi ed è ben possibile che tale limite non sia mai raggiunto, cosa che rimanda la liberazione delle connessioni al momento dello spegnimento dolce (esaurimento dei Thread in esecuzione) della JVM. Se tale tipo di spegnimento non si verifichi, è inoltre possibile che la connessione sopravviva alla JVM.

Anche quella di creare un oggetto che incapsuli la base dati è un'intuizione molto "OO" e, più generale, ottima per quanto riguarda l'approccio alla scrittura di un'applicazione, se consideriamo "bene" isolare quelle inevitabili parti di un sistema che siano dipendenti da risorse esterne alla logica dell'applicazione.

Potremmo pensare ad una cosa del genere:

Codice:
public abstract class DBObject {
    private Database database = DBFactory.getDatabase(); //ipotesi

    public void set(DBObject who, Object field, Object newValue) {
        database.update(who, field, newValue);
    }

    public Object get(DBObject who, Object field) {
        return database.get(who, field);
    }
}

e poi:

Codice:
public class Persona extends DBObject {

    public void setAltezza(int altezza) {
        update(this, "altezza", altezza);
    }

    public int getAltezza() {
        return get(this, "altezza");
    }
}
Qui "Database" è l'ipotetica rappresentazione della base dati e DBFactory il creatore di questo Database. Ovviamente si tratta di null'altro che uno spostamento del problema delle connessioni. Tuttavia, propagando un oggetto che rappresenti il concetto di "database", sei libero di concentrare in un solo punto del sistema le tue decisioni in tema di gestione delle connessioni.

Puoi aprirne e chiuderne una ad ogni invocazione di update o get ma noterei come la presenza di un delegato alla gestione della persistenza delle "persone" favorisca l'ipotesi di una connessione unica.
scusa... non se sbaglio oppure no... ma penso che hai fatto un piccolo sbaglio di trascrizione ma potrei di gran lunga sbagliare ... non tocco il java da 2 anni

nella setAltezza non dovresti richiamare set invece che update?

ciao e scusami ancora
SaintTDI è offline   Rispondi citando il messaggio o parte di esso
Old 22-03-2006, 20:27   #7
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Sbagli!!! Infatti gli errori sono due, non uno .

Pardon, ho scritto il codice mentre pensavo a che codice scrivere e poi l'ho cambiato al volo tanto per aumentare la probabilità di scrivere castronerie.

Fermo restando lo scopo di esemplificare un'idea, la forma meno imbarazzante avrebbe potuto essere:

Codice:
public class Persona extends DBObject {

    public void setAltezza(int altezza) {
        set(this, "altezza", altezza);
    }

    public int getAltezza() {
        Object value = get(this, "altezza");
        if(value instanceof Number) {
             return ((Number)value).intValue();
        } else {
            throw new RuntimeException("Poffare, una stranezza!");
        }
    }
}
Grazie per la segnalazione.
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 22-03-2006, 23:56   #8
SaintTDI
Senior Member
 
L'Avatar di SaintTDI
 
Iscritto dal: Jul 2004
Città: Roma
Messaggi: 2094
Quote:
Originariamente inviato da PGI-Bis
Sbagli!!! Infatti gli errori sono due, non uno .

Pardon, ho scritto il codice mentre pensavo a che codice scrivere e poi l'ho cambiato al volo tanto per aumentare la probabilità di scrivere castronerie.

Fermo restando lo scopo di esemplificare un'idea, la forma meno imbarazzante avrebbe potuto essere:

Codice:
public class Persona extends DBObject {

    public void setAltezza(int altezza) {
        set(this, "altezza", altezza);
    }

    public int getAltezza() {
        Object value = get(this, "altezza");
        if(value instanceof Number) {
             return ((Number)value).intValue();
        } else {
            throw new RuntimeException("Poffare, una stranezza!");
        }
    }
}
Grazie per la segnalazione.
ah ecco

beh io non ho capito esattamente che fa il getAltezza adesso come adesso perchè come ti ho detto non tocco java da 2 anni

che fai... fai il get di "altezza" e controlli se è un numero...se è un numero cosa fai esattamente? cosa ritorni? Ovvero che vuol dire questo:
return ((Number)value).intValue();

Altrimenti se non è un numero c'è un eccezione? giusto?
è solamente una finezza?

scusa per le domande niubbe
SaintTDI è offline   Rispondi citando il messaggio o parte di esso
Old 23-03-2006, 00:32   #9
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Premetto che è solo un'idea di funzionamento, nel concreto è possibile che ci siano soluzioni migliori.

getAltezza, come rilevi, deve restituire un int.

DBObject permette lo scambio di riferimenti Object tra il richiedente e l'ipotetica base dati.

Così ipotizzo che la base dati legga un "int" (che non è un Object), lo incapsuli in un Integer (che è un Object), e lo restituisca come valore per il "get(DBObject, Object)" a cui si appoggia "getAltezza".

Ciò che per contratto è un Object, in getAltezza è presupposto Integer.

Al livello di getAltezza non è strettamente necessario sapere che il valore ottenuto sia un Tipo Integer. Ciò che conta è che sia un valore numerico intero che, nel campo dei "wrapper" (Byte, Short, Integer, Float, Double), è rappresentato da Number.

Così converto quell'Object in Number. Il tipo Number definisce, tra gli altri, il metodo "intValue" che restituisce il valore del numero (che potrebbe essere un qualsiasi wrapper di primitivo) come "int".

Che quell'Object sia un Number è però tutt'altro che certo, in Persona. Il fatto che "value" NON sia un Number è, per getAltezza, un'eccezione.

Un'eccezione è una condizione il cui verificarsi impedisce ad un'istruzione o ad un blocco di istruzioni, accomunate dall'identità di scopo, di adempiere con successo allo scopo che le accomuna.

Secondo una certa teoria delle eccezioni, poichè il verificarsi dell'errore eccezionale non dipende da un comportamento di chi invochi il metodo getAltezza, la notifica del mancato raggiungimento dell'obiettivo (restituire un valore per l'altezza) deve essere segnalata attraverso un'eccezione non controllata.

Questa è la ragione della conversione di value a Number, dell'invocazione di intValue e del rilascio di un'eccezione RuntimeException (e non, per dire, un Exception semplice).
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 23-03-2006, 00:43   #10
SaintTDI
Senior Member
 
L'Avatar di SaintTDI
 
Iscritto dal: Jul 2004
Città: Roma
Messaggi: 2094
Quote:
Originariamente inviato da PGI-Bis
Premetto che è solo un'idea di funzionamento, nel concreto è possibile che ci siano soluzioni migliori.

getAltezza, come rilevi, deve restituire un int.

DBObject permette lo scambio di riferimenti Object tra il richiedente e l'ipotetica base dati.

Così ipotizzo che la base dati legga un "int" (che non è un Object), lo incapsuli in un Integer (che è un Object), e lo restituisca come valore per il "get(DBObject, Object)" a cui si appoggia "getAltezza".

Ciò che per contratto è un Object, in getAltezza è presupposto Integer.

Al livello di getAltezza non è strettamente necessario sapere che il valore ottenuto sia un Tipo Integer. Ciò che conta è che sia un valore numerico intero che, nel campo dei "wrapper" (Byte, Short, Integer, Float, Double), è rappresentato da Number.

Così converto quell'Object in Number. Il tipo Number definisce, tra gli altri, il metodo "intValue" che restituisce il valore del numero (che potrebbe essere un qualsiasi wrapper di primitivo) come "int".

Che quell'Object sia un Number è però tutt'altro che certo, in Persona. Il fatto che "value" NON sia un Number è, per getAltezza, un'eccezione.

Un'eccezione è una condizione il cui verificarsi impedisce ad un'istruzione o ad un blocco di istruzioni, accomunate dall'identità di scopo, di adempiere con successo allo scopo che le accomuna.

Secondo una certa teoria delle eccezioni, poichè il verificarsi dell'errore eccezionale non dipende da un comportamento di chi invochi il metodo getAltezza, la notifica del mancato raggiungimento dell'obiettivo (restituire un valore per l'altezza) deve essere segnalata attraverso un'eccezione non controllata.

Questa è la ragione della conversione di value a Number, dell'invocazione di intValue e del rilascio di un'eccezione RuntimeException (e non, per dire, un Exception semplice).
grande ho quasi capito al 100 % mi mancano solo delle mie piccole lacune

grazie tante

purtroppo lavorare in Siebel fa questi brutti scherzi devi ripendere la mano in Java... ASSOLUTAMENTE!
SaintTDI è offline   Rispondi citando il messaggio o parte di esso
Old 23-03-2006, 01:10   #11
carosene
Member
 
Iscritto dal: Jan 2004
Messaggi: 173
Sono giunto a questa conclusione:

Codice:
import java.sql.*;

public abstract class DBObject {
    
    private static Connection cn;
    
    /**
     * Registra il driver,inizializza cn...
     */
    public static void avviaConnessione() throws SQLException{
        ...   
    }
    
    /**
     * Chiude cn
     */
    public static void terminaConnessione() throws SQLException{
        ...    
    }
    
    /**
     * Esegue la query passata come parametro per operazioni di selezione
     */
    public ResultSet seleziona(String query){
        ...    
    }
    
    /**
     * Esegue la query passata come parametro
     * @return Restituisce il numero dei record modificati
     */
    public int update(String query){
        ...
    }
    
}
Questa classe mi permette di usare la stessa connessione in tutti gli oggetti che la estendono. Inoltre ho una grande flessibilità.

Cosa ne pensate?

Ultima modifica di carosene : 23-03-2006 alle 10:36.
carosene è offline   Rispondi citando il messaggio o parte di esso
Old 23-03-2006, 13:31   #12
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Alla fine della fiera, devi decidere tu quale sia l'approccio che meglio si addice al sistema che vuoi creare, per come l'hai pensato.

Il codice che hai scritto è certamente conforme al proposito di condividere la connessione alla base dati.

Renderà più semplice il sistema? Eh eh, domanda da un milione di dollari . Prova a scrivere un prototipo o un progetto dettagliato usando quella classe e potrai verificarlo.
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Wind Tre 'accende' il 5G Standalone in Italia: si apre una nuova era basata sui servizi Wind Tre 'accende' il 5G Standalone in Italia: s...
OPPO Find X9 Pro: il camera phone con teleobiettivo da 200MP e batteria da 7500 mAh OPPO Find X9 Pro: il camera phone con teleobiett...
DJI Romo, il robot aspirapolvere tutto trasparente DJI Romo, il robot aspirapolvere tutto trasparen...
DJI Osmo Nano: la piccola fotocamera alla prova sul campo DJI Osmo Nano: la piccola fotocamera alla prova ...
FUJIFILM X-T30 III, la nuova mirrorless compatta FUJIFILM X-T30 III, la nuova mirrorless compatta
Nexperia, l'incontro tra Trump e Xi Jinp...
GPU RDNA 1 RX 5000 e RDNA 2 RX 6000, AMD...
Google Maps avrà una modalit&agra...
HONOR sta lavorando a uno smartphone con...
Thermaltake MAGFloe 360 Ultra ARGB Sync:...
Xiaomi 15T ora in super offerta su Amazo...
Si stringe il cerchio attorno a TP-Link ...
Amazon cambia i prezzi ancora una volta:...
Imperdibili i Google Pixel 10 a questi p...
Dyson OnTrac in super offerta su Amazon:...
Amazon: la nuova ondata di licenziamenti...
Questo portatile è un mostro: MSI...
Apple Watch Series 11 GPS + Cellular cro...
JBL Clip 5 in forte sconto su Amazon: lo...
Il nuovo top di gamma compatto di OnePlu...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 07:42.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v