Tårer og smerte
Det kan oppstå feil under kjøring av et Java-program. Når du arbeider med databasen vil det oppstå feil. Det handler om hvilke av dem du kan forutsi og tilby en adekvat løsning.
Den første store gruppen av feil vil vente på deg når du utfører denne linjen:
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "secret");
Hva kan du forvente her?
Feil 1. Driver ikke funnet .
Hvis du får feilmeldingen "Ingen passende driver funnet for ..." betyr det at DriverManager ikke kunne forstå hvilken type DBMS som ligger bak URL-en din. For eksempel skrev du jdbc_mysql: i stedet for jdbc:mysql:
Feil 2. Tilkoblingsfeil .
Hvis du gjør en feil i vertsnavnet, vil du mest sannsynlig få en melding som "Ingen slik vert er kjent" eller "Communications link failure".
Feil 3. Databasenavnet er feil .
Hvis du feilstavet databasenavnet eller kobler til en annen server der det ikke eksisterer, vil du få en melding som "Ukjent database 'supershop3'" .
Feil 4. Feil pålogging eller passord .
Hvis du har glemt databasepassordet eller skrevet det inn feil, vil du mest sannsynlig motta en melding som "Tilgang nektet for brukeren 'root'@'localhost' (bruker passord: JA)" .
SQL-unntak
Hvis forbindelsen til basen likevel er etablert, vil det være mer interessant videre. Ved feil ved arbeid med databasen har JDBC et spesielt unntak - java.sql.SQLException . Samt flere av dens varianter.
Dette unntaket har bare én ekstra metode (sammenlignet med Exception-klassen) - metoden getSQLSate(), som returnerer statuskoden (strengen) som SQL-serveren returnerte til den. Feilhåndtering ser slik ut:
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();
}
Det er hundrevis av feilkoder. Du kan se hele listen her .
Men noen ganger hjelper feilkoder JDBC med å forstå feilen bedre, og da kaster den ikke bare SQLException, men spesialisert SQLException:
BatchUpdateException | Feil under gruppeforespørsel |
DataTrunkering | Oppstår ofte ved trunkering av lange data |
SQLClientInfoException | Klienten sendte parametere som ikke kan settes på tilkoblingen: Tilkobling |
SQLDataException | Feil med data, detaljer avhenger av typen DBMS |
SQLException | Databasetilgangsfeil eller andre generelle feil |
SQLFeatureNotSupportedException | DBMS støtter ikke denne funksjonaliteten |
SQLIntegrityConstraintViolationException | Alle feil med for SQLState ==22 |
SQLInvalidAuthorizationSpecException | Tilgangs- og/eller autorisasjonsfeil |
SQLNonTransientConnectionException | Alle feil med for SQLState ==08 |
SQLRecoverableException | Det er en feil, men den kan fikses ved hjelp av søknaden |
SQLSyntaxErrorException | Feil i søkesyntaks |
SQLTimeoutException | Forespørselen tok for lang tid |
SQLTransactionRollbackException | Feil under tilbakeføring av transaksjon |
SQL-advarsel | Advarsel utstedt av DBMS |
Eksempler på feil
Hvis det oppstod en feil på stadiet av serverapplikasjonen, kan den vanligvis bare logges og deretter behandles mer detaljert. Men hvis det skjedde mens applikasjonen kjørte på programmererens datamaskin, må du nøye undersøke årsaken til dette.
Det er to største kategorier av feil når du arbeider med en database:
- Forespørselstekstfeil
- Feil under arbeid med ResultSet
En feil i forespørselsteksten kan oppstå svært ofte. Spørringen kan være veldig lang, inneholde flere tabeller (samlet via JOIN) og underspørringer (SUBSELECT). Det er ikke lett å finne en feil i en slik forespørsel. I tillegg er forespørsler ofte limt sammen fra deler, data legges til der.
Den aller første feilen du bør være klar over er SQLSyntaxErrorException . En slik feil betyr vanligvis at du har en skrivefeil i forespørselsteksten.
La oss ta vårt favoritteksempel:
ResultSet results = statement.executeQuery("SELECT Count(*) FROM user");
results.next();
int count = results.getInt(1);
Og "ved et uhell" sletter stjernen i forespørselsteksten:
ResultSet results = statement.executeQuery("SELECT Count() FROM user");
results.next();
int count = results.getInt(1);
Da får vi et unntak:
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)
SQL-serveren forteller oss at det var en syntaksfeil før FROM.
Vi ser nøye på forespørselen og tenker. Hvis ingenting kommer til tankene, og dette skjer veldig ofte, må du be noen om å se hva som er galt.
En annen populær feil er feil arbeid med ResultSet - resultatet av forespørselen. Anta at du glemte at før du leser dataene, kommer den "gjeldende raden" til ResultSet-objektet før den første raden, da vil du ha følgende kode:
ResultSet results = statement.executeQuery("SELECT Count(*) FROM user");
// results.next();
int count = results.getInt(1);
Du får denne feilen:
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)
Vi ser nøye på feilen og tenker. Så googler vi og finner et par eksempler og prøver å forstå løsningen.