JDBC 異常簡介 jDBC簡介(六)


SQL 異常簡介

對於數據庫的操作訪問,必然也很可能拋出異常
JDBC中定義了SQLException,用於描述數據庫相關操作中可能出現的異常情況。
java.sql.SQLException 
 
異常本質沒有什么特別的邏輯,通常借助於異常的名稱傳達異常的類型,通過攜帶的信息進行進一步分析
SQLException是SQL相關的異常的始祖 ,主要有以下擴展:
  • BatchUpdateException
  • RowSetWarning
  • SerialException
  • SQLClientInfoException
  • SQLNonTransientException
  • SQLRecoverableException
  • SQLTransientException
  • SQLWarning
  • SyncFactoryException
  • SyncProviderException 
每個 SQLException 都可提供以下多種消息:
特定於每個供應商的整數錯誤代碼 。通常,這將是底層數據庫返回的實際錯誤代碼。
描述錯誤的字符串 。此字符串用作 Java Exception 消息,可以通過方法 getMessage 獲得(繼承來的方法)。
"SQLstate" 字符串 ,該字符串遵守 XOPEN SQLstate 約定或 SQL:2003 約定。SQLState 字符串的值在適當的規范中描述。DatabaseMetaData 的方法 getSQLStateType 可用於確定驅動程序返回 XOPEN 類型還是 SQL:2003 類型。
到下一個 Exception 的鏈接可以使用此鏈接提供其他錯誤信息。
因果關系,如果存在任何導致此 SQLException 的原因。 

方法列表如下:

int getErrorCode()
          獲取此 SQLException 對象的特定於供應商的異常代碼。
String getSQLState()
          獲取此 SQLException 對象的 SQLState。
Iterator<Throwable> iterator()
          返回在鏈接的 SQLExceptions 上進行迭代的迭代器。
void setNextException(SQLException ex)
          將 SQLException 對象添加到鏈接的末尾。
SQLException getNextException()
          通過 setNextException(SQLException ex) 獲取鏈接到此 SQLException 對象的異常

異常處理

下面是第一個JDBC示例中的代碼,沒有很好地處理異常,直接throws Exception了
package jdbc.jdbc;


import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.Statement;


/**

* 第一個JDBC

* @author noteless

*/

public class FirstJDBC {

public static void main(String[] args) throws Exception {

//1、注冊驅動

Class.forName("com.mysql.jdbc.Driver");

//數據庫連接所需參數

String user = "root";

String password = "123456";

String url = "jdbc:mysql://localhost:3306/sampledb?useUnicode=true&characterEncoding=utf-8";

//2、獲取連接對象

Connection conn = DriverManager.getConnection(url, user, password);

//設置sql語句

String sql = "select * from student";

//3、獲得sql語句執行對象

Statement stmt = conn.createStatement();

//4、執行sql並保存結果集

ResultSet rs = stmt.executeQuery(sql);

//5、處理結果集

while (rs.next()) {

System.out.print("id:" + rs.getInt(1));

System.out.print(",姓名:" + rs.getString(2));

System.out.print(",年齡:" + rs.getInt(3));

System.out.println(",性別:" + rs.getString(4));

}

//6、資源關閉

rs.close();

stmt.close();

conn.close();

}

}

 

對於可能拋出異常的代碼,應該使用try包裹
不管如何,資源最終都應該被關閉,但是如果資源在打開前就出現異常,直接關閉可能會出現問題
而且在資源關閉過程中也可能出現異常
一個稍微規范一點的形式可能如下所示
package jdbc;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

public class FirstJDBCFormal {

public static void main(String[] args) throws Exception {


//1、注冊驅動

Class.forName("com.mysql.jdbc.Driver");


//數據庫連接所需參數

String user = "root";

String password = "123456";

String url = "jdbc:mysql://localhost:3306/sampledb?useUnicode=true&characterEncoding=utf-8";

Connection conn = null;

Statement stmt = null;

ResultSet rs = null;

try {

//2、獲取連接對象

conn = DriverManager.getConnection(url, user, password);


//3、設置sql語句

String sql = "select * from student";


//4、獲得sql語句執行對象

stmt = conn.createStatement();



//5、執行並保存結果集

rs = stmt.executeQuery(sql);



//6、處理結果集

while (rs.next()) {

System.out.print("id:" + rs.getInt(1));

System.out.print(",姓名:" + rs.getString(2));

System.out.print(",年齡:" + rs.getInt(3));

System.out.println(",性別:" + rs.getString(4));

}

} catch (Exception e) {

throw new RuntimeException(e);

} finally {

//7、資源關閉

try {

if (conn != null) {

conn.close();

}

if (rs != null) {

rs.close();

}

if (stmt != null) {

stmt.close();

}
} catch (SQLException e) {

}
}
}
}

 

最后一塊的finally也可以處理成下面這種形式
if (conn != null) {

try{

conn.close();

}catch (SQLException e){


}

}

if (rs != null) {

try{

rs.close();

}catch (SQLException e){


}

}

if (stmt != null) {

try{

stmt.close();

}catch (SQLException e){

}

}

 

注意:
catch()后面都應該做些處理的,上面的示例中也省略了

總結

對於JDBC中的異常,我們重點在於要認識常見的異常,以及出現異常的原因,能夠通過異常信息得到對問題有一個基本的定位
現在借助於各種框架工具,根本就不需要手動編寫JDBC程序,更別說自己處理JDBC中的異常了
但是,借助於框架底層的一些異常仍舊是根源於JDBC,所以需要對JDBC中的異常有一個簡單了解,以及如何使用
 
在執行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);

}

}

 

 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM