Lacrimi și durere
Pot apărea erori în timpul rulării unui program Java. Când lucrați cu baza de date, vor apărea erori. Totul este despre care dintre ele poți prezice și oferi o soluție adecvată.
Primul grup mare de erori vă va aștepta când executați această linie:
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "secret");
La ce te poți aștepta aici?
Eroare 1. Driverul nu a fost găsit .
Dacă primești eroarea „Nu s-a găsit un driver adecvat pentru...” , înseamnă că DriverManager nu a putut înțelege ce tip de SGBD se află în spatele adresei URL. De exemplu, ați scris jdbc_mysql: în loc de jdbc:mysql:
Eroare 2. Eroare de conectare .
Dacă faceți o greșeală în numele gazdei, cel mai probabil veți primi un mesaj de genul „Nu se cunoaște o astfel de gazdă” sau „Eșec de legătură de comunicare”.
Eroare 3. Numele bazei de date este incorect .
Dacă ați scris greșit numele bazei de date sau vă conectați la un alt server unde acesta nu există, veți primi un mesaj de genul „Bază de date necunoscută „supershop3”” .
Eroare 4. Autentificare sau parolă greșită .
Dacă ați uitat parola bazei de date sau ați introdus-o incorect, atunci cel mai probabil veți primi un mesaj de genul „Acces refuzat pentru utilizatorul 'root'@'localhost' (folosind parola: YES)” .
Excepție SQL
Dacă conexiunea la bază este totuși stabilită, atunci va fi mai interesant în continuare. În cazul unor erori la lucrul cu baza de date, JDBC are o excepție specială - java.sql.SQLException . La fel și câteva dintre soiurile sale.
Această excepție are o singură metodă suplimentară (comparativ cu clasa Exception) - metoda getSQLState(), care returnează codul de stare (șir) pe care serverul SQL l-a returnat. Gestionarea erorilor arată astfel:
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "secret");
try {
int rowsCount = statement.executeUpdate("DELETE FROM ‘Unemployees’");
} catch (SQLException ex) {
// If table doesn't exist
if (ex.getSQLState().compareTo("X0Y32") != 0) {
throw ex;
}
} finally {
connection.close();
}
Există sute de coduri de eroare. Lista completă o puteți vedea aici .
Dar, uneori, codurile de eroare ajută JDBC să înțeleagă mai bine eroarea și apoi aruncă nu doar SQLException, ci și SQLException specializată:
BatchUpdateException | Eroare la solicitarea grupului |
Truncarea datelor | Apare adesea la trunchierea datelor lungi |
SQLClientInfoException | Clientul a transmis parametri care nu pot fi setati la conexiune: Conexiune |
SQLDataException | Eroare cu datele, detaliile depind de tipul de SGBD |
SQLException | Eroare de acces la baza de date sau alte erori generale |
SQLFeatureNotSupportedException | DBMS nu acceptă această funcționalitate |
SQLIntegrityConstraintViolationException | Toate erorile cu pentru SQLState ==22 |
SQLInvalidAuthorizationSpecException | Eroare de acces și/sau autorizare |
SQLNonTransientConnectionException | Toate erorile cu pentru SQLState ==08 |
SQLRecoverableException | Există o eroare, dar poate fi remediată cu intervenția aplicației |
SQLSyntaxErrorException | Eroare în sintaxa interogării |
SQLTimeoutException | Solicitarea a durat prea mult |
SQLTransactionRollbackException | Eroare la derularea tranzacției |
SQLWarning | Avertisment emis de SGBD |
Exemple de erori
Dacă a apărut o eroare în stadiul aplicației server, atunci de obicei poate fi doar înregistrată și apoi tratată mai detaliat. Dar dacă s-a întâmplat în timp ce aplicația rula pe computerul programatorului, atunci trebuie să investigați cu atenție motivul pentru aceasta.
Există două mari clase de erori atunci când lucrați cu o bază de date:
- Eroare de text de solicitare
- Eroare la lucrul cu ResultSet
O eroare în textul solicitării poate apărea foarte des. Interogarea poate fi foarte lungă, conține mai multe tabele (unite prin JOIN) și subinterogări (SUBSELECT). Nu este ușor să găsiți o eroare într-o astfel de solicitare. În plus, cererile sunt adesea lipite împreună din părți, datele sunt adăugate acolo.
Prima eroare de care ar trebui să fii conștient este SQLSyntaxErrorException . O astfel de eroare înseamnă de obicei că aveți o greșeală de scriere în corpul solicitării.
Să luăm exemplul nostru preferat:
ResultSet results = statement.executeQuery("SELECT Count(*) FROM user");
results.next();
int count = results.getInt(1);
Și ștergeți „accidental” asteriscul din corpul solicitării:
ResultSet results = statement.executeQuery("SELECT Count() FROM user");
results.next();
int count = results.getInt(1);
Atunci vom obține o excepție:
Exception in thread "main" java.sql.SQLSyntaxErrorException:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') FROM task' at line 1
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
Serverul SQL ne spune că a existat o eroare de sintaxă înainte de FROM.
Privim cu atenție cererea și ne gândim. Dacă nu-ți vine nimic în minte, iar acest lucru se întâmplă foarte des, atunci trebuie să ceri pe cineva să se uite ce este în neregulă.
O altă greșeală populară este munca incorectă cu ResultSet - rezultatul solicitării. Să presupunem că ați uitat că înainte de a citi datele, „rândul curent” al obiectului ResultSet vine înaintea primului rând, atunci veți avea următorul cod:
ResultSet results = statement.executeQuery("SELECT Count(*) FROM user");
// results.next();
int count = results.getInt(1);
Veți primi această eroare:
2012 12:55:48 AM jButton5ActionPerformed
SEVERE: null
java.sql.SQLException: Before start of result set
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
at com.mysql.jdbc.ResultSetImpl.checkRowPos(ResultSetImpl.java:841)
at com.mysql.jdbc.ResultSetImpl.getStringInternal(ResultSetImpl.java:5650)
at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5570)
Ne uităm cu atenție la eroare și ne gândim. Apoi căutăm pe google și găsim câteva exemple și încercăm să înțelegem soluția.