Lavorare sulle basi dati con JDBC

di il
105 risposte

105 Risposte - Pagina 3

  • Re: Lavorare sulle basi dati con JDBC

    DATABASE



    Hai ragione è sbagliato usare SERIAL e poi scrivere gli indici. Così è molto meglio:
    INSERT INTO utenti (id, nome, password) VALUES
    (DEFAULT, 'Topolino', '...'),
    (DEFAULT, 'Pippo', '...'),
    (DEFAULT, 'Pluto', '...'),
    (DEFAULT, 'Paperino', '...');
    E' tutto scritto qui: http://www.postgresqltutorial.com/postgresql-serial. Ti ringrazio moltissimo.
    Ho letto qualcosa su FOREIGN KEY e mi sembra di capire che mi stai consigliando di valutare questa opzione:
    CREATE TABLE utenti (
    	id SERIAL PRIMARY KEY,
    	nome VARCHAR(255) NOT NULL,
    	password VARCHAR(255) NOT NULL,
    	UNIQUE (nome)
    );
    CREATE TABLE spostamenti (
    	id SERIAL PRIMARY KEY,
    	id_utente INT NOT NULL,
    	latitudine DOUBLE PRECISION NOT NULL,
    	longitudine DOUBLE PRECISION NOT NULL,
    	tempo TIMESTAMP NOT NULL,
    	velocita DOUBLE PRECISION,
    	FOREIGN KEY (id_utente) REFERENCES utenti (id)
    );
    Se ho capito bene, correggimi se sbaglio, la riga seguente:
    FOREIGN KEY (id_utente) REFERENCES utenti (id)
    ricorda al database che id_utente ed id sono legate.
    A questa pagina:

    leggo questo:
    1.nella tabella secondaria (nel mio caso spostamenti), inserisco una nuova riga o modifico la chiave esterna. Si noti che la cancellazione di una riga dalla tabella secondaria non viola mai il vincolo di chiave esterna;
    2.nella tabella principale, cancello una riga o modifico la chiave riferita. Si noti che l'inserimento di una nuova riga dalla tabella principale non viola mai il vincolo di chiave esterna.
    e la cosa mi scoraggia per questi motivi:
    a.Un utente può avere più posizioni diverse ovvero ad un id possono corrispondere diverse righe nella tabella spostamenti.
    b.Potrei decidere di eliminare un utente e tutte le sue posizioni dal database.
    Quesiti:
    alfa.Ho compreso a fondo il quesito?
    beta.Mi consigli di usare oppure no FOREIGN KEY?


    CODICE JAVA


    Ho notato che il processo di lettura, modifica, inserimento e cancellazione di informazioni dal DB è simile così mi stavo chiedendo se era possibile creare un unico metodo per fare tutto. Ovviamente non proprio tutto quanto ma almeno il 90% delle query.
    Stavo pensando ad un metodo di questo tipo:
    public void queryGenerica(Connection connessione, String query, String… valoriQuery, String... leggiColonne) throws SQLException {}
    query potrebbe essere la semplice query con i punti interrogativi (esempio: "SELECT * FROM utenti WHERE id = ?;") mentre valoriQuery le stringhe da sostituire ai relativi "?" e da verificare con i vari setQualchecosa() (perdona il linguaggio poco ortodosso...). leggiColonne le colonne da leggere e da fornire a next().
    Inoltre sarebbe bello inserire in un unico file non annegato in una valanga di codice i dati di accesso al DB.
    Altra cosa antipatica è creare ogni volta l'oggetto connessione.
    Ecco il mio codice:
    import java.sql.*;
    
    public class Main {
    
        static {
            try {
                Class.forName("org.postgresql.Driver");
            } catch (ClassNotFoundException e) {
                throw new ExceptionInInitializerError(e);
            }
        }
    
        private final String url = "jdbc:postgresql://192.168.99.103:5432/gis";
        private final String user = "eb";
        private final String password = "password";
    
        public Connection connect() {
            Connection conn = null;
            try {
                conn = DriverManager.getConnection(url, user, password);
                System.out.println("Connesso al server PostgreSQL con successo.");
            } catch (SQLException e) {
                System.out.println(e.getMessage());
            }
            return conn;
        }
    
        public void doQuery(Connection conn, Integer p1) throws SQLException {
            PreparedStatement ps = null;
            try {
                String query = "SELECT * FROM utenti";
                if (p1 != null) {
                    query = query + " WHERE id = ?";
                    ps = conn.prepareStatement(query);
                    ps.setInt(1, p1);
                } else {
                    ps = conn.prepareStatement(query);
                }
                readAndProcessData(ps.executeQuery());
            } catch (Exception e){
                System.out.println("Impossibile connettersi al database oppure preparare la query.");
            } finally {
                try {
                    if (ps != null) ps.close();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
    
        public void readAndProcessData(ResultSet rs) throws SQLException {
            try {
                String id, nome, password;
                while (rs.next()) {
                    id = rs.getString("id");
                    nome = rs.getString("nome");
                    password = rs.getString("password");
                    System.out.println(id + " " + nome + " " + " " + password);
                }
            } finally {
                try {
                    rs.close();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
    
        public static void main(String[] args) {
            System.out.println("Studio di PostgreSQL");
            Main Main = new Main();
            Connection connessione = Main.connect();
            try {
                Main.doQuery(connessione, 1);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    Quesiti:
    gamma.Dovrei lavorare con i generic?
    delta.Potrebbe essere una cosa fattibile?
    epsilon.C'è già qualcosa di pronto da qualche parte?
    Grazie
  • Re: Lavorare sulle basi dati con JDBC

    giannino1995 ha scritto:


    INSERT INTO utenti (id, nome, password) VALUES
    (DEFAULT, 'Topolino', '...'),
    (DEFAULT, 'Pippo', '...'),
    (DEFAULT, 'Pluto', '...'),
    (DEFAULT, 'Paperino', '...');
    Sì, così. Oppure in alternativa (l'avevo detto già prima):
    INSERT INTO utenti (nome, password) VALUES
    ('Topolino', '...'),
    ('Pippo', '...'),
    ('Pluto', '...'),
    ('Paperino', '...');
    ovvero non elenchi proprio il id. Dà lo stesso risultato perché il id ha comunque il default dalla sequence.

    giannino1995 ha scritto:


    Se ho capito bene, correggimi se sbaglio, la riga seguente:
    FOREIGN KEY (id_utente) REFERENCES utenti (id)
    ricorda al database che id_utente ed id sono legate.
    Sì, c'è un "vincolo di integrità" a livello di DB che sostanzialmente impone:
    - in spostamenti.id_utente puoi solo mettere id utente che "esistono". Se in utenti hai solo id 1, 2, 3, 4, allora in id_utente non puoi mettere es. 10 che non esiste.
    - non puoi eliminare l'utente se è referenziato da almeno un record in spostamenti.

    Questi sono vincoli di integrità, servono appunto a mantenere "integra" la base dati.

    giannino1995 ha scritto:


    a.Un utente può avere più posizioni diverse ovvero ad un id possono corrispondere diverse righe nella tabella spostamenti.
    E questo è perfettamente possibile. Non c'entra nulla se il vincolo di foreign key c'è oppure no. E' una comune relazione uno-a-molti.

    giannino1995 ha scritto:


    b.Potrei decidere di eliminare un utente e tutte le sue posizioni dal database.
    Se lo scenario è questo, se NON c'è la foreign key, puoi eliminare i record nell'ordine che vuoi (prima l'utente e poi in spostamenti o viceversa). Chiaramente in modo "atomico", cioè in una transazione.

    Se c'è la foreign key, devi PRIMA eliminare i record in spostamenti e POI l'utente (non viceversa, che non sarebbe possibile).

    Ma è anche possibile fare un'altra cosa: mettere il ON DELETE CASCADE alla foreign key. Così fai solo un delete sull'utente e in automatico vengono eliminati anche i record referenzianti in spostamenti.
  • Re: Lavorare sulle basi dati con JDBC

    giannino1995 ha scritto:


    Ho notato che il processo di lettura, modifica, inserimento e cancellazione di informazioni dal DB è simile così mi stavo chiedendo se era possibile creare un unico metodo per fare tutto. Ovviamente non proprio tutto quanto ma almeno il 90% delle query.
    Stavo pensando ad un metodo di questo tipo:
    public void queryGenerica(Connection connessione, String query, String… valoriQuery, String... leggiColonne) throws SQLException {}
    query potrebbe essere la semplice query con i punti interrogativi (esempio: "SELECT * FROM utenti WHERE id = ?;") mentre valoriQuery le stringhe da sostituire ai relativi "?" e da verificare con i vari setQualchecosa() (perdona il linguaggio poco ortodosso...). leggiColonne le colonne da leggere e da fornire a next().
    Se dovrai poi fare svariate query (e specialmente se per tipi differenti di dati), può aver senso creare delle astrazioni che permettono di riutilizzare il codice e non "sporcare" altre parti del tuo codice. Ma NON così come stavi pensando (dare solo in pasto i nomi delle colonne è molto vago e banale).

    Queste sono questioni più di "design". Dovresti ragionare più in termini di un "template".

    Se hai bisogno di fare una query che dà una lista di N oggetti estraendo dal result dei dati che metti in ciascun oggetto, questa è grosso modo la forma generale:

    a) crea(/ottieni) Connection
    b) crea PreparedStatement, setta eventuali parametri
    c) esegui la query
    d) crea un ArrayList<X>
    d) cicla sul ResultSet, per ciascuna riga:
    ......d1) crea un oggetto X
    ......d2) popola l'oggetto X con dei dati dalla riga corrente
    ......d3) aggiungi l'oggetto nella lista
    e) chiudi il ResultSet
    f) chiudi il PreparedStatement
    g) chiudi la Connection
    h) restituisci la lista

    Se al posto di X avessi tipi differenti, es. Libro, Persona, Corso, Città, Veicolo, ecc... COSA cambia e cosa NON cambia? Quello che non cambia lo devi tenere comune, quello che cambia lo devi incapsulare e rendere separabile dal resto. Insomma bisogna ragionare (molto) a livello object-oriented.

    giannino1995 ha scritto:


    Inoltre sarebbe bello inserire in un unico file non annegato in una valanga di codice i dati di accesso al DB.
    Il codice di accesso ad un DB si fa generalmente in classi dedicate e separate dal resto (ovvero, non in una Servlet, non in una JSP).

    giannino1995 ha scritto:


    Altra cosa antipatica è creare ogni volta l'oggetto connessione.
    Questa è un'altra questione. Nelle web-application, generalmente NON si crea una Connection ad ogni query. Si utilizzano tipicamente delle librerie di connection-pooling.

    Poi se tu per prove iniziali, test ecc.. ti basta fare così, ok. Ma va fatto oculatamente (la Connection va sempre chiusa, in qualunque caso, ecc..)

    giannino1995 ha scritto:


    gamma.Dovrei lavorare con i generic?
    Se devi gestire delle liste di oggetti es. Utente, SÌ
  • Re: Lavorare sulle basi dati con JDBC

    Per quanto riguarda il database ho fatto la modifica e testato il tutto.
    In gergo popolesco si direbbe: "Una gran figata!".
    Io ho sempre pensato al DB come a qualcosa di statico ma non è affatto così.
    Grazie infinite! Sei un pozzo di scienza!
    A tuo avviso tra le 3 opzioni seguenti quale useresti? (vorrei usare almeno 2 tabelle)
    Opzione 1
    CREATE TABLE utenti (
    	id SERIAL PRIMARY KEY,
    	nome VARCHAR(255) NOT NULL,
    	password VARCHAR(255) NOT NULL,
    	UNIQUE (nome)
    );
    CREATE TABLE spostamenti (
    	id SERIAL PRIMARY KEY,
    	id_utente INT NOT NULL REFERENCES utenti (id) ON DELETE CASCADE,
    	latitudine DOUBLE PRECISION NOT NULL,
    	longitudine DOUBLE PRECISION NOT NULL,
    	tempo TIMESTAMP NOT NULL,
    	velocita DOUBLE PRECISION,
    	FOREIGN KEY (id_utente) REFERENCES utenti (id)
    );
    
    Opzione 2:
    CREATE TABLE utenti (
    	id SERIAL PRIMARY KEY,
    	nome VARCHAR(255) NOT NULL,
    	password VARCHAR(255) NOT NULL,
    	UNIQUE (nome)
    );
    CREATE TABLE spostamenti (
    	id SERIAL PRIMARY KEY,
    	nome_utente VARCHAR(255) NOT NULL REFERENCES utenti (nome) ON DELETE CASCADE,
    	latitudine DOUBLE PRECISION NOT NULL,
    	longitudine DOUBLE PRECISION NOT NULL,
    	tempo TIMESTAMP NOT NULL,
    	velocita DOUBLE PRECISION,
    	FOREIGN KEY (nome_utente) REFERENCES utenti (nome)
    );
    Opzione 3:
    CREATE TABLE utenti (
    	nome VARCHAR(255) NOT NULL,
    	password VARCHAR(255) NOT NULL,
    	UNIQUE (nome)
    );
    CREATE TABLE spostamenti (
    	nome_utente VARCHAR(255) NOT NULL REFERENCES utenti (nome) ON DELETE CASCADE,
    	latitudine DOUBLE PRECISION NOT NULL,
    	longitudine DOUBLE PRECISION NOT NULL,
    	tempo TIMESTAMP NOT NULL,
    	velocita DOUBLE PRECISION,
    	FOREIGN KEY (nome_utente) REFERENCES utenti (nome)
    );
    ciao
  • Re: Lavorare sulle basi dati con JDBC

    giannino1995 ha scritto:


    A tuo avviso tra le 3 opzioni seguenti quale useresti? (vorrei usare almeno 2 tabelle)
    Ehm ... no alt. Forse hai le idee ancora abbastanza confuse.

    Primo:
    Innanzitutto il REFERENCES che metti sulla colonna o più sotto nella clausola FOREIGN KEY, NON sono due cose completamente differenti! Sono la stessa cosa concettualmente!

    Solo che se è sulla colonna, ovviamente il riferimento da-a è solo per 1 (UNA) colonna (insomma, è una forma abbreviata).
    Se è con la clausola FOREIGN KEY (quindi per la tabella in generale), puoi specificare più colonne (nel caso es. di chiave primaria composta).

    Quindi o una o l'altra forma.

    Secondo:
    Una colonna "testo" (oltretutto VARCHAR(255) !) che "punta" ad un'altra colonna di testo (in un'altra tabella) è una cavolata pazzesca.

    Terzo:
    Una tabella come:
    CREATE TABLE utenti (
    	nome VARCHAR(255) NOT NULL,
    	password VARCHAR(255) NOT NULL,
    	UNIQUE (nome)
    );
    che non ha una chiave primaria, è un'altra cavolata pazzesca.
  • Re: Lavorare sulle basi dati con JDBC

    Ok sul secondo e terzo punto ma sul primo non concordo o non comprendo. Se scrivo questo:
    CREATE TABLE utenti (
    	id SERIAL PRIMARY KEY,
    	nome VARCHAR(255) NOT NULL,
    	password VARCHAR(255) NOT NULL,
    	UNIQUE (nome)
    );
    CREATE TABLE spostamenti (
    	id SERIAL PRIMARY KEY,
    	id_utente INT NOT NULL REFERENCES utenti (id) ON DELETE CASCADE,
    	latitudine DOUBLE PRECISION NOT NULL,
    	longitudine DOUBLE PRECISION NOT NULL,
    	tempo TIMESTAMP NOT NULL,
    	velocita DOUBLE PRECISION,
    	FOREIGN KEY (id_utente) REFERENCES utenti (id)
    );
    Riesco a cancellare un utente che ha delle posizioni in 'spostamenti'. In pratica quando faccio un delete sull'utente in automatico elimino anche i record referenzianti in spostamenti. Se scrivo questo:
    CREATE TABLE utenti (
    	id SERIAL PRIMARY KEY,
    	nome VARCHAR(255) NOT NULL,
    	password VARCHAR(255) NOT NULL,
    	UNIQUE (nome)
    );
    CREATE TABLE spostamenti (
    	id SERIAL PRIMARY KEY,
    	id_utente INT NOT NULL,
    	latitudine DOUBLE PRECISION NOT NULL,
    	longitudine DOUBLE PRECISION NOT NULL,
    	tempo TIMESTAMP NOT NULL,
    	velocita DOUBLE PRECISION,
    	FOREIGN KEY (id_utente) REFERENCES utenti (id)
    );
    non riesco a cancellare un utente che ha dei record in 'spostamenti'.
    A me pare che la prima opzione sia quella più completa. Non posso commettere errori nel creare la tabella 'spostamenti' e al contempo posso eliminare utenti e relative posizioni con una semplice query di questo tipo:
    DELETE FROM utenti WHERE id = ...;
    Non riesco a capire il DB che hai in mente per me. Per caso stai dicendo che sarebbe meglio scrivere così:
    CREATE TABLE spostamenti (
    	id SERIAL PRIMARY KEY,
    	id_utente INT NOT NULL,
    	latitudine DOUBLE PRECISION NOT NULL,
    	longitudine DOUBLE PRECISION NOT NULL,
    	tempo TIMESTAMP NOT NULL,
    	velocita DOUBLE PRECISION,
    	FOREIGN KEY (id_utente) REFERENCES utenti (id) ON DELETE CASCADE
    );



    Per quanto riguarda il codice java non riesco a capire come chiudere la connessione. Per esempio questo codice a me non funziona:
        public void doQuery(Connection conn, Integer p1) throws SQLException {
            PreparedStatement ps = null;
            try {
                String query = "SELECT * FROM utenti";
                if (p1 != null) {
                    query = query + " WHERE id = ?";
                    ps = conn.prepareStatement(query);
                    ps.setInt(1, p1);
                } else {
                    ps = conn.prepareStatement(query);
                }
                readAndProcessData(ps.executeQuery());
            } catch (Exception e){
                System.out.println("Impossibile connettersi al database oppure preparare la query.");
            } finally {
                try {
                    if (ps != null) ps.close();
                    conn.close();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
    Infatti se faccio una nuova query mi accorgo che questo metodo non viene più invocato:
    public Connection connect() {
            Connection conn = null;
            try {
                conn = DriverManager.getConnection(url, user, password);
                System.out.println("Connesso al server PostgreSQL con successo.");
            } catch (SQLException e) {
                System.out.println(e.getMessage());
            }
            return conn;
        }
    Infatti non leggo più "Connesso al server PostgreSQL con successo." nella shell di IntelliJ.
    Perché questo codice non funziona?
    conn.close();
  • Re: Lavorare sulle basi dati con JDBC

    giannino1995 ha scritto:


    Ok sul secondo e terzo punto ma sul primo non concordo o non comprendo. Se scrivo questo:
    Allora:

    O metti:
        id_utente INT NOT NULL REFERENCES utenti (id) ON DELETE CASCADE,
    (e nessuna clausola FOREIGN KEY)

    oppure metti:
        id_utente INT NOT NULL,
      .......
        FOREIGN KEY (id_utente) REFERENCES utenti (id) ON DELETE CASCADE
    Sono la STESSA cosa.
  • Re: Lavorare sulle basi dati con JDBC

    Ok, grazie.
    Ho lavorato su un metodo per generalizzare l'interrogazione del DB:
    
        class Generic<T> {
            T ob;
            Generic(T o) {
                ob = o;
            }
            T getob() {
                return ob;
            }
            void showType() {
                System.out.println(M.strSum("Il tipo di T è ", ob.getClass().getName()));
            }
        }
    public ArrayList<String> Query(String query, Generic<?>... parametriQuery) throws SQLException {
            Connection conn = connect();
            PreparedStatement ps = null;
            try {
                int i = 1;
                for(Generic<?> o : parametriQuery){
                    if (o != null) {
                        ps = conn.prepareStatement(query);
                        if (o.getob() instanceof String) {
                            ps.setString(i++, (String) o.getob());
                        } else if (o.getob() instanceof Integer) {
                            ps.setInt(i++, (Integer) o.getob());
                        } else if (o.getob() instanceof Double) {
                            ps.setDouble(i++, (Double) o.getob());
                        } else if (o.getob() instanceof Date) {
                            ps.setDate(i++, (java.sql.Date) o.getob());
                        } else if (o.getob() instanceof Double) {
                            ps.setDouble(i++, (Double) o.getob());
                        } else {
                            System.out.println("Tipo di parametro mancante.");
                            throw new RuntimeException();
                        }
                    } else {
                        ps = conn.prepareStatement(query);
                    }
                }
                // (*)
                return outputQuery(ps.executeQuery());
            } catch (Exception e){
                System.out.println("Impossibile connettersi al database oppure preparare la query.");
            } finally {
                try {
                    if (ps != null) {
                        ps.close();
                    }
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            return null;
        }
        // Vedi (*) - Al momento una bozza...
        public ArrayList<String> outputQuery(ResultSet rs) throws SQLException {
            ArrayList<String> arrayList = new ArrayList();
            try {
                String id, nome, password;
                while (rs.next()) {
                    id = rs.getString("id");
                    nome = rs.getString("nome");
                    password = rs.getString("password");
                    System.out.println(id + " " + nome + " " + " " + password);
                    arrayList.add(id);
                    arrayList.add(nome);
                    arrayList.add(password);
                    return arrayList;
                }
            } finally {
                try {
                    rs.close();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            return null;
        }
        public static void main(String[] args) {
            System.out.println("Studio di PostgreSQL");
            System.out.println("");
            System.out.println("Test della classe PostgreSQL");
            PostgreSQL PostgreSQL = new PostgreSQL();
            try {
                PostgreSQL.doQuery(PostgreSQL.connect(), 1);
                ArrayList<String> arrayList = new ArrayList();
                Generic<Integer> id = new Generic<Integer>(1);
                arrayList = PostgreSQL.Query("SELECT * FROM utenti WHERE id = ?", id);
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    Cosa ne pensi?
    Per migliorare ulteriormente la mia classe cosa mi consigli?
    L'unica cosa che non so come fare è chiudere la connessione... il metodo seguente a me non funziona, non chiude nulla...
    conn.close();
  • Re: Lavorare sulle basi dati con JDBC

    Non ha assolutamente alcun senso fare una classe "generica" come quella Generic e poi .... la usi come Generic<?>

    Zero ...
  • Re: Lavorare sulle basi dati con JDBC

    andbin ha scritto:


    Non ha assolutamente alcun senso fare una classe "generica" come quella Generic e poi .... la usi come Generic<?>

    Zero ...
    Quindi come generalizzeresti l'interrogazione al DB?
  • Re: Lavorare sulle basi dati con JDBC

    giannino1995 ha scritto:


    Quindi come generalizzeresti l'interrogazione al DB?
    Almeno per la forma (signature) del metodo, prendi "spunto" dal JdbcTemplate di Spring.

    https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html

    (i metodi query, es quelli che ritornano un List<T> )
  • Re: Lavorare sulle basi dati con JDBC

    andbin ha scritto:


    giannino1995 ha scritto:


    Quindi come generalizzeresti l'interrogazione al DB?
    Almeno per la forma (signature) del metodo, prendi "spunto" dal JdbcTemplate di Spring.

    https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html

    (i metodi query, es quelli che ritornano un List<T> )
    Non ho ancora studiato Spring, prima di quel capitolo ce ne sono altri.
    Non capisco...
  • Re: Lavorare sulle basi dati con JDBC

    giannino1995 ha scritto:


    Non ho ancora studiato Spring, prima di quel capitolo ce ne sono altri.
    Non capisco...
    Non ho detto che devi usare Spring .... ti ho indicato di GUARDARE la forma dei query del JdbcTemplate.

    Uno dei suoi query() più semplici è:

    public <T> List<T> query(String sql, Object[] args, RowMapper<T> rowMapper)

    EDIT: p.s. cerca di capire cosa rappresenta quel RowMapper. E riprendi la risposta che avevo dato prima, quella dove indicavo genericamente grosso modo le fasi per fare una query per una lista di oggetti, dove avevo messo i punti a) b) .... h). Dato che non avevi risposto prima, allora richiedo: QUALI sono i passi secondo te che NON possono essere fatti (perché cambiano da una query ad un'altra) da un metodo di query "generalizzato" come in quella sequenza?
  • Re: Lavorare sulle basi dati con JDBC

    Non sono in grado. L'unica cosa che sono riuscito a fare è questa:
    import java.sql.*;
    import java.util.ArrayList;
    import java.util.Date;
    
    public class PostgreSQL {
    
    	public ArrayList<String> Query(String query, Generic<?>... parametriQuery) throws SQLException {
            Connection conn = connect();
            PreparedStatement ps = null;
            ResultSet rs = null;
            try {
                int i = 1;
                ps = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
                for(Generic<?> parametro : parametriQuery){
                    if (parametro != null) {
                        if (parametro.getob() instanceof String) {
                            ps.setString(i++, (String) parametro.getob());
                        } else if (parametro.getob() instanceof Integer) {
                            ps.setInt(i++, (Integer) parametro.getob());
                        } else if (parametro.getob() instanceof Double) {
                            ps.setDouble(i++, (Double) parametro.getob());
                        } else if (parametro.getob() instanceof Date) {
                            java.sql.Timestamp timestamp = new java.sql.Timestamp(((Date) parametro.getob()).getTime());
                            ps.setTimestamp(i++, timestamp);
                        } else {
                            System.out.println("Tipo di parametro mancante.");
                            throw new RuntimeException();
                        }
                    }
                }
                if (query.contains("SELECT")) {
                    rs = ps.executeQuery();
                    ArrayList<String> arrayList = new ArrayList();
                    while (rs.next()) {
                        arrayList.add(rs.getString("id"));
                        arrayList.add(rs.getString("nome"));
                        arrayList.add(rs.getString("password"));
                    }
                    return arrayList;
                } else {
                    ps.executeUpdate();
                    rs = ps.getGeneratedKeys();
                    int key = 0;
                    if (rs.next()) {
                        key = rs.getInt(1);
                    }
                    ArrayList<String> arrayList = new ArrayList();
                    arrayList.add(Integer.toString(key));
                    return arrayList;
                }
            } catch (Exception e){
                System.out.println(e.getMessage());
                System.out.println("Impossibile connettersi al database oppure eseguire la query.");
            } finally {
                try {
                    if (conn != null) {
                        conn.close();
                    }
                    if (ps != null) {
                        ps.close();
                    }
                    if (rs != null) {
                        rs.close();
                    }
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            return null;
        }
    
    }
    
    class Generic<T> {
        T ob;
        Generic(T o) {
            ob = o;
        }
        T getob() {
            return ob;
        }
        void showType() {
            System.out.println(new MetodiApplicazione().strSum("Il tipo di T è ", ob.getClass().getName()));
        }
    }
    Non è molto ma fa quello che deve fare.
  • Re: Lavorare sulle basi dati con JDBC

    giannino1995 ha scritto:


    Non sono in grado.
    Non so (più) che dire ......
    Come sei messo sul fronte OOP? Perché altrimenti Spring Framework, se volessi mai affrontarlo, ti risulterà altamente ostico.
Devi accedere o registrarti per scrivere nel forum
105 risposte