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

發佈了111 篇原創文章 · 獲贊 158 · 訪問量 37萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章