andbin ha scritto:
giannino1995 ha scritto:
4) se qualcosa va storto devo informare il chiamante con uno 0 per INSERT e false con UPDATE e DELETE;
NOOO. Se qualcosa va storto (= SQLException, qualcosa di grave), SQLException deve USCIRE dal metodo.
1.Se non la fai uscire hai già innanzitutto un comportamento difforme rispetto agli altri metodi (oltre al fatto che non è più vero il throws SQLException).
1.La mia intenzione era evitare che il codice si bloccasse ma in effetti se qualcosa non funziona la webapp va bloccata. Penserò a questo aspetto quando ritorno alla webapp.
andbin ha scritto:
giannino1995 ha scritto:
6) il tuo costrutto non mi piace perché è rischioso:
A cosa ti riferisci esattamente??
2.Mi riferisco al fatto che se lancio un ps.setString() dopo un PreparedStatement senza aprire un nuovo Try commetto un errore. Inoltre tutti questi finaly non mi piacciano, rendono il codice difficile da leggere. La tua soluzione è validissima, non travisare le mie parole ma preferisco avere un unico finaly nel codice.
3.Un’altra cosa che ho notato testando il nuovo codice (vedi a fine post), ma che sicuramente si verifica anche nel precedente, è che quando tento di mettere un record che poi non può essere inserito per un motivo o per l’altro nel DB viene perso un id come quando scrivo un record e poi lo cancello. Detto in altro modo se tento di aggiungere un record che esiste già il mio metodo mi avverte e non aggiunge nulla al DB ma al passaggio successivo (un nuovo INSERT) il DB salta un id. Posso tranquillamente fregarmene oppure devo evitare questo comportamento? Rischio di ridurre la capienza massima del mio DB?
4.Nel codice trovi due nuovi metodi:
isAcceptable(): è una classe aggiunta a
DBMSUtente.java per verificare che la user e la password non siano nulle o contengano degli spazi oppure ancora prive di caratteri.
DBMSConnessione.close(rs , ps , c): è un semplice costruttore del tuo close(AutoCloseable c).
package DBMS;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class DBMSUtenteDAOPostgreSQL implements DBMSUtenteDAO {
DBMSConnessione DBMSConnessione = new DBMSConnessione();
public List<DBMSUtente> findAll() throws SQLException {
Connection c = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
c = DBMSConnessione.connect();
ps = c.prepareStatement("SELECT * FROM utenti");
rs = ps.executeQuery();
List<DBMSUtente> lista = new ArrayList<DBMSUtente>();
while (rs.next()) {
DBMSUtente utente = new DBMSUtente();
utente.setId(rs.getLong("id"));
utente.setNome(rs.getString("nome"));
utente.setPassword(rs.getString("password"));
lista.add(utente);
}
if (lista.size()==0) {
System.out.println("La tabella è vuota.");
lista = null;
} else {
System.out.println("E' stato possibile recuperare i record dalla tabella.");
}
return lista;
} catch (Exception e) {
System.out.println("Non è stato possibile recuperare i record dalla tabella.");
List<DBMSUtente> lista = null;
return lista;
} finally {
DBMSConnessione.close(rs , ps , c);
}
}
public DBMSUtente findByNome(String nome) throws SQLException {
Connection c = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
c = DBMSConnessione.connect();
ps = c.prepareStatement("SELECT * FROM utenti WHERE nome = ?");
ps.setString(1, nome);
rs = ps.executeQuery();
if (rs.next()) {
DBMSUtente utente = new DBMSUtente();
utente.setId(rs.getLong("id"));
utente.setNome(rs.getString("nome"));
utente.setPassword(rs.getString("password"));
System.out.println("E' stato possibile trovare il record.");
return utente;
} else {
DBMSUtente utente = null;
System.out.println("Non è stato possibile trovare il record.");
return utente;
}
} catch (Exception e) {
System.out.println("Non è stato possibile recuperare il record dalla tabella.");
DBMSUtente utente = null;
return utente;
} finally {
DBMSConnessione.close(rs , ps , c);
}
}
public DBMSUtente findById(Long id) throws SQLException {
Connection c = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
c = DBMSConnessione.connect();
ps = c.prepareStatement("SELECT * FROM utenti WHERE id = ?");
ps.setLong(1, id);
rs = ps.executeQuery();
if (rs.next()) {
DBMSUtente utente = new DBMSUtente();
utente.setId(rs.getLong("id"));
utente.setNome(rs.getString("nome"));
utente.setPassword(rs.getString("password"));
System.out.println("E' stato possibile trovare il record.");
return utente;
} else {
DBMSUtente utente = null;
System.out.println("Non è stato possibile trovare il record.");
return utente;
}
} catch (Exception e) {
System.out.println("Non è stato possibile recuperare il record dalla tabella.");
DBMSUtente utente = null;
return utente;
} finally {
DBMSConnessione.close(rs , ps , c);
}
}
public Long insert(DBMSUtente u) throws SQLException {
Connection c = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
if(!u.isAcceptable()) {
System.out.println("Non è stato possibile inserire il record.");
return 0L;
}
c = DBMSConnessione.connect();
ps = c.prepareStatement("INSERT INTO utenti (nome, password) VALUES (? , ?)");
ps.setString(1, u.getNome());
ps.setString(2, u.getPassword());
ps.executeUpdate(ps.toString(), PreparedStatement.RETURN_GENERATED_KEYS);
rs = ps.getGeneratedKeys();
Long idRiga = 0L;
if (rs.next()) {
idRiga = rs.getLong(1);
System.out.println("E' stato possibile inserire il record nell'id: " + idRiga);
}
return idRiga;
} catch (Exception e) {
System.out.println("Non è stato possibile inserire il record.");
return 0L;
} finally {
DBMSConnessione.close(rs , ps , c);
}
}
public boolean update(DBMSUtente u) throws SQLException {
Connection c = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
if(!u.isAcceptable()) {
System.out.println("Non è stato possibile inserire il record.");
return false;
}
c = DBMSConnessione.connect();
ps = c.prepareStatement("UPDATE utenti SET nome = ?, password = ? WHERE id = ?");
ps.setString(1, u.getNome());
ps.setString(2, u.getPassword());
ps.setLong(3, u.getId());
Long numRighe = Long.valueOf(ps.executeUpdate());
if(numRighe!=0){
System.out.println("E' stato aggiornato il record.");
return true;
}else{
System.out.println("Record non trovato.");
return false;
}
} catch (Exception e) {
System.out.println("Non è stato possibile inserire il record.");
return false;
} finally {
DBMSConnessione.close(rs , ps , c);
}
}
public boolean delete(DBMSUtente u) throws SQLException {
Connection c = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
c = DBMSConnessione.connect();
ps = c.prepareStatement("DELETE FROM utenti WHERE id = ?");
ps.setLong(1, u.getId());
Long numRighe = Long.valueOf(ps.executeUpdate());
if(numRighe!=0){
System.out.println("E' stato cancellato il record.");
return true;
}else{
System.out.println("Record non trovato.");
return false;
}
} catch (Exception e) {
System.out.println("Non è stato possibile cancellare il record.");
return false;
} finally {
DBMSConnessione.close(rs , ps , c);
}
}
}
5.Bellezza, grazia ed eleganza a parte la mia classe può andare oppure a tuo avviso ha gravi problemi di funzionalità e sicurezza?
migliorabile ha scritto:
1) in generale la "configurazione" (ip del DBMS, utente, password, ecc) si tengono in un FILE separato (ad esempio un file '.properties' , '.json' o '.xml')
2) anche le query si tengono, spesso, in un file separato, perche' possono dover essere modificate
3) NON SI USA MAI il "System.out" per fare logging, ma librerie dedicate.
Java ha la sua implementazione, ma c'e' anche Log4J, molto famosa, o Apache Commons Logging
Grazie migliorabile per i consigli.
A.Quindi creeresti un file di questo tipo:
...\src\main\webapp\WEB-INF\DBMS.json
e salveresti sopra di esso ip, utente e password? Useresti quindi la mia classe attuale DBMS.java non per conservare le credenziali del DB ma per leggere le informazioni da DBMS.json, ho capito bene?
B.Nel mio caso ho creato un package ma credo che basti altrimenti diventa tutto troppo frammentato. Se decidessi di cambiare DB basterebbe creare una nuova classe ed editare sopra le 6 query, non sarebbe un lavoro faticoso. Grazie ugualmente del consiglio.
C.Perché "System.out" non va bene? Cosa offre di più un logger?