泪与痛
运行 Java 程序时可能会出现错误。使用数据库时,会发生错误。这完全取决于您可以预测其中的哪些并提供适当的解决方案。
执行此行时,第一大组错误将等待您:
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "secret");
你能在这里期待什么?
错误 1.未找到驱动程序。
如果您收到错误“No suitable driver found for …”,这意味着 DriverManager 无法理解您的 URL 后面的 DBMS 类型。例如,你写了 jdbc_mysql: 而不是 jdbc:mysql:
错误 2.连接错误。
如果您输入的主机名有误,您很可能会收到类似“不知道这样的主机”或“通信链接失败”之类的消息。
错误3,数据库名称不正确。
如果您拼错了数据库名称或连接到另一个不存在的服务器,您将收到一条消息,如“Unknown database 'supershop3'”。
错误 4.登录名或密码错误。
如果您忘记了数据库密码或输入错误,那么您很可能会收到类似“用户 'root'@'localhost'(使用密码:YES)的访问被拒绝”的消息。
SQL异常
如果仍然建立了与基地的联系,那么它将更加有趣。如果在使用数据库时出现错误,JDBC 有一个特殊的异常 - java.sql.SQLException。以及它的几个品种。
这个异常只有一个额外的方法(与Exception类相比)——getSQLState()方法,它返回SQL服务器返回给它的状态码(字符串)。错误处理如下所示:
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();
}
有数百个错误代码。您可以在此处查看完整列表。
但有时错误代码有助于 JDBC 更好地理解错误,然后它不仅抛出 SQLException,而且抛出专门的 SQLException:
批量更新异常 | 群组请求期间出错 |
数据截断 | 经常发生在截断长数据时 |
SQLClientInfoException异常 | 客户端传递了无法在连接上设置的参数:Connection |
SQL数据异常 | 数据错误,详细信息取决于 DBMS 的类型 |
SQL异常 | 数据库访问错误或其他一般错误 |
SQLFeatureNotSupportedException | DBMS 不支持此功能 |
SQLIntegrityConstraintViolationException | SQLState ==22 的所有错误 |
SQLInvalidAuthorizationSpecException | 访问和/或授权错误 |
SQLNonTransientConnectionException | SQLState ==08 的所有错误 |
SQLRecoverableException | 有错误,但可以通过应用程序的干预来修复 |
SQL语法错误异常 | 查询语法错误 |
SQL超时异常 | 请求时间过长 |
SQLTransactionRollbackException | 事务回滚时出错 |
SQL警告 | DBMS发出的警告 |
错误示例
如果在服务器应用阶段发生了错误,那么通常只能记录下来,然后再进行更详细的处理。但如果它是在应用程序在程序员的计算机上运行时发生的,那么您需要仔细调查造成这种情况的原因。
使用数据库时有两类最大的错误:
- 请求文本错误
- 使用 ResultSet 时出错
请求文本中的错误经常发生。查询可以很长,包含多个表(通过 JOIN 连接)和子查询 (SUBSELECT)。在这样的请求中不容易发现错误。此外,请求通常由多个部分粘合在一起,在那里添加数据。
您应该注意的第一个错误是SQLSyntaxErrorException。这种错误通常意味着您在请求正文中有错别字。
让我们举一个我们最喜欢的例子:
ResultSet results = statement.executeQuery("SELECT Count(*) FROM user");
results.next();
int count = results.getInt(1);
并“不小心”删除了请求正文中的星号:
ResultSet results = statement.executeQuery("SELECT Count() FROM user");
results.next();
int count = results.getInt(1);
然后我们会得到一个异常:
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 Server 告诉我们 FROM 之前有一个语法错误。
我们仔细查看请求并思考。如果什么都没有想到,而且这种情况经常发生,那么你需要请人看看哪里出了问题。
另一个常见的错误是不正确地使用 ResultSet——请求的结果。假设你忘记了在读取数据之前,ResultSet对象的“当前行”排在第一行之前,那么你就会有如下代码:
ResultSet results = statement.executeQuery("SELECT Count(*) FROM user");
// results.next();
int count = results.getInt(1);
你会得到这个错误:
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)
大家仔细看看错误,思考一下。然后我们谷歌并找到几个例子并尝试理解解决方案。