2015-07-04 38 views
1
public class EmployeeDaoImpl extends JdbcDaoSupportImpl implements EmployeeDao { 

    @Override 
    public int save(Employee employee) throws EmployeeException { 
     String sql = "INSERT INTO EMPLOYEE VALUES(?,?,?)"; 
     Connection conToUse = null; 
     PreparedStatement ps = null; 
     int status = 0; 
     try { 
      conToUse = getConnection(); 
      ps = conToUse.prepareStatement(sql); 
      ps.setInt(1, employee.getEmpNo()); 
      ps.setString(2, employee.getEmpName()); 
      ps.setLong(3, employee.getEmpSal()); 
      status = ps.executeUpdate(); 
     } catch (SQLException e) { 
      // TODO Auto-generated catch block 
      throw new EmployeeException(
        "%%% Exception occured in EmployeeDao save() %%% " + e); 
     } finally { 
      DbUtils.closeQuietly(ps); 
     } 
     return status; 
    } 

} 

在示例代碼中,EmployeeDaoImpl類將插入記錄到數據庫中。如果發生任何異常,則將EmployeeException(應用程序異常)拋出到服務層。拋出用戶定義的異常需要什麼?在這種情況下,我們也可以拋出SQLException,是否正確?而不是重新拋出用戶定義的異常,我們可以重新拋出Dao中的SQLException和ClassNotFound異常嗎?

回答

1

在這種情況下,不需要拋出用戶定義的異常。 SQLException應該足夠了。

如果Connection對象拋出定義的異常,用戶定義的異常將更有意義。

只要你發現異常並對它做些什麼,那就是最重要的。

0

是這些類型的異常可以按原樣拋出。 如果你有一個UI前端或某種類型的客戶端,那麼把它作爲用戶異常包裝並拋出是有意義的。

1

您不應該拋出ClassNotFoundExceptions,因爲DAO不應該負責創建數據庫連接。我希望getConnection從某個地方(可能是threadlocal)檢索現有連接,並將它放在請求中的較早位置。如果它創建一個連接,那麼它不會關閉它,這將是不好的。此外,您應該使用連接池(再次導致移動可能會將DAO外部的某個ClassNotFoundException引發的代碼)。

對於大多數SQLExceptions,你不能對它們做任何事情,但讓它們冒泡,取消當前的工作單元,然後捕獲並記錄在異常處理程序中,因此檢查異常是一件煩惱。 Spring在這裏做了正確的事情,它將SQLExceptions轉換爲更有意義但未經檢查的DataAccessExceptions,其中不同類型的子類型用於不同類型的錯誤。如果您發現自己需要捕獲違反RI約束時拋出的異常,則會捕獲DataIntegrityViolationException,而無需擔心數據庫供應商使用的SQLState,因爲Spring已經爲您翻譯了它。

有了這個未經檢查的DataAccessException,沒有理由再有一個特定於應用程序的包裝器異常。