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引發。