Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Cineca inaugura Pitagora, il supercomputer Lenovo per la ricerca sulla fusione nucleare
Cineca inaugura Pitagora, il supercomputer Lenovo per la ricerca sulla fusione nucleare
Realizzato da Lenovo e installato presso il Cineca di Casalecchio di Reno, Pitagora offre circa 44 PFlop/s di potenza di calcolo ed è dedicato alla simulazione della fisica del plasma e allo studio dei materiali avanzati per la fusione, integrandosi nell’ecosistema del Tecnopolo di Bologna come infrastruttura strategica finanziata da EUROfusion e gestita in collaborazione con ENEA
Mova Z60 Ultra Roller Complete: pulisce bene grazie anche all'IA
Mova Z60 Ultra Roller Complete: pulisce bene grazie anche all'IA
Rullo di lavaggio dei pavimenti abbinato a un potente motore da 28.000 Pa e a bracci esterni che si estendono: queste, e molte altre, le caratteristiche tecniche di Z60 Ultra Roller Complete, l'ultimo robot di Mova che pulisce secondo le nostre preferenze oppure lasciando far tutto alla ricca logica di intelligenza artificiale integrata
Renault Twingo E-Tech Electric: che prezzo!
Renault Twingo E-Tech Electric: che prezzo!
Renault annuncia la nuova vettura compatta del segmento A, che strizza l'occhio alla tradizione del modello abbinandovi una motorizzazione completamente elettrica e caratteristiche ideali per i tragitti urbani. Renault Twingo E-Tech Electric punta su abitabilità, per una lunghezza di meno di 3,8 metri, abbinata a un prezzo di lancio senza incentivi di 20.000€
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


Cineca inaugura Pitagora, il supercomputer Lenovo per la ricerca sulla fusione nucleare Cineca inaugura Pitagora, il supercomputer Lenov...
Mova Z60 Ultra Roller Complete: pulisce bene grazie anche all'IA Mova Z60 Ultra Roller Complete: pulisce bene gra...
Renault Twingo E-Tech Electric: che prezzo! Renault Twingo E-Tech Electric: che prezzo!
Il cuore digitale di F1 a Biggin Hill: l'infrastruttura Lenovo dietro la produzione media Il cuore digitale di F1 a Biggin Hill: l'infrast...
DJI Osmo Mobile 8: lo stabilizzatore per smartphone con tracking multiplo e asta telescopica DJI Osmo Mobile 8: lo stabilizzatore per smartph...
Hai usato il 'Pezzotto'? Ora anche la Se...
TeraFab: Musk vuole costruire la fabbric...
Lo compri una volta, lo giochi dove vuoi...
Qiantinuum annuncia Helios, "il com...
Samsung Galaxy S26 Ultra: una sola novit...
Google prepara Gemini 3 Pro e Nano Banan...
TVS non è solo moto e scooter: ec...
Alexa+ arriva su BMW: gli automobilisti ...
Gemini Deep Research arriva su Google Fi...
Rinvii a catena, Marvel 1943: Rise of Hy...
Xiaomi inaugura uno spazio dedicato ai f...
Rilasciate le specifiche di Bluetooth 6....
L'obiettivo che mette tutto a fuoco: la ...
Meta avrebbe raccolto fino al 10% dei ri...
NVIDIA DGX Spark e videogiochi? Una pess...
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: 08:06.


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