【JDBC4.2】JDBC中的Exception
JDBC中的异常类包括SQLException类和它的子类们。
1.SQLException
SQLException包含下面信息:
信息项 | 获取方法 | 备注 |
---|---|---|
错误描述 | SQLException#getMessage | |
SQLState | SQLException#getSQLState | |
error code | SQLException#getMessage | |
cause | SQLException#getCause | 递归获取一个异常上的Throwable |
多个异常 | SQLException#getNextException递归 | 如果已经没有异常,返回null |
对Chained Execeptions的支持
chained exceptions :异常链或链式异常
在java代码中常常会再捕获一个异常后抛出另外一个异常,并且希望把异常原始信息保存下来,这被称为异常链
JDK1.4以后,所有Throwable的子类子构造器中都可以接受一个cause对象作为参数,这个cause就异常原由,代表着原始异常,即使在当前位置创建并抛出行的异常,也可以通过这个cause追踪到异常最初发生的位置。比如:throw new RuntimeException("ex---2",e1);
把e1加载到另一个异常的异常链上。
SQLException对异常链的支持包括:
1.增加了构造函数支持cause Throwable参数
2.可以使用ForEach循环获取所有Cause(代替每次getNextException后调用getCause)
3.getCause可能返回一个非SQLException的Exception
定位SQLExceptions的代码
在执行SQL的时候,可能会出现多个Exception,每个Exception都有它们自己的Cause。可以递归使用getNextException获取所有的Exception,每次获取Exception时候再递归调用getCause获取所有Cause Throwable。
try{
//...
}catch(SQLException ex) {
while(ex != null) {
System.out.println("SQLState:" + ex.getSQLState());
System.out.println("Error Code:" + ex.getErrorCode());
System.out.println("Message:" + ex.getMessage());
Throwable t = ex.getCause();
while(t != null) {
System.out.println("Cause:" + t);
t = t.getCause();
}
ex = ex.getNextException();
}
}
使用ForEach直接获取所有Cause Throwable
try{
//...
}catch(SQLException ex) {
for(Throwable e : ex ) {
System.out.println("Error encountered: " + e);
}
}
2.SQLWarning
SQLWarning是SQLException的子类,下面这些接口的实现类的getWarnings方法会生成SQLWarning
■ Connection
■ DataSet
■ Statement
■ ResultSet
如果出现多个SQLWarning,他们会被串联到第一个SQLWarning上,通过getNextWarning方法递归地获取所有SQLWarning
3.DataTruncation数据截断
DataTruncation是SQLWarning的子类,当数据库中的数据被截断时,会生成此对象。比如:
数据库中student表的name是varchar(5),当我保存超过五个字符。
Connection connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/test?serverTimezone=UTC",
"root",
"123456");
Statement statement = connection.createStatement();
int rows = statement.executeUpdate("INSERT INTO student(name,age) VALUES ('TooLongName',19)");
会抛出如下异常:
try{
Connection connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/test?serverTimezone=UTC",
"root",
"123456");
Statement statement = connection.createStatement();
int rows = statement.executeUpdate("INSERT INTO student(name,age) VALUES ('TooLongName',19)");
statement.close();
connection.close();
}catch (DataTruncation e){
System.out.println(e.getSQLState());//22001为写入,01004为读取
System.out.println(e.getMessage());
System.out.println(e.getParameter());
//...其他方法
}
5.BatchUpdateException
批量更新(BatchUpdate)产生的异常。
6.分类的异常Categorized SQLExceptions
这些异常可以和特定的 SQLStates相关:
■ SQLNonTransientException
■ SQLTransientException
■ SQLRecoverableException
NonTransient SQLExceptions
通常是由代码错误引起的,重试后任然会执行失败。异常出现时,Connection仍然有效。
包含SQLFeatureNotSupportedException,SQLNonTransientConnectionException,SQLDataException,SQLIntegrityConstraintViolationException,SQLInvalidAuthorizationException,SQLSyntaxErrorException等
SQLTransientException
通常不是由代码错误引起的,重新执行后可能会成功。异常出现时,Connection仍然有效。
包括SQLTransientConnectionException,SQLTransactionRollbackException,SQLTimeoutException等。
SQLRecoverableException
需要关闭Connection,重新建立。异常出现时,Connection不再有效。
7.SQLClientinfoException
该异常由Connection.setClientInfo引发。