[英]Better way for DB exception handling in java
哪一種更好:針對這種情況的ErrorCode或Exception?
我見過這兩種錯誤處理技術。 我不知道每種技術的優缺點。
public void doOperation(Data data) throws MyException {
try {
// do DB operation
} catch (SQLException e) {
/* It can be ChildRecordFoundException, ParentRecordNotFoundException
* NullValueFoundException, DuplicateException, etc..
*/
throw translateException(e);
}
}
要么
public void doOperation(Data data) throws MyException {
try {
// do DB operation
} catch (SQLException e) {
/* It can be "CHILD_RECORD_FOUND, "PARENT_RECORD_NOT_FOUND"
* "NULL_VALUE_FOUND", "DUPLICATE_VALUE_FOUND", etc..
*/
String errorCode = getErrorCode(e);
MyException exc = new MyException();
exc.setErrorCode(errorCode);
throw exc;
}
}
對於第二種方法,錯誤代碼檢索表單配置文件。 我們可以基於SQL Vender Code
添加Error Code
SQL Vender Code
。
SQL_ERROR_CODE.properties
#MySQL Database
1062=DUPLICATE_KEY_FOUND
1216=CHILD_RECORD_FOUND
1217=PARENT_RECORD_NOT_FOUND
1048=NULL_VALUE_FOUND
1205=RECORD_HAS_BEEN_LOCKED
方法1的呼叫者客戶端
try {
} catch(MyException e) {
if(e instanceof ChildRecordFoundException) {
showMessage(...);
} else if(e instanceof ParentRecordNotFoundException) {
showMessage(...);
} else if(e instanceof NullValueFoundException) {
showMessage(...);
} else if(e instanceof DuplicateException) {
showMessage(...);
}
}
方法2的呼叫者客戶端
try {
} catch(MyException e) {
if(e.getErrorCode().equals("CHILD_RECORD_FOUND")) {
showMessage(...);
} else if(e.getErrorCode().equals("PARENT_RECORD_NOT_FOUND") {
showMessage(...);
} else if(e.getErrorCode().equals("NULL_VALUE_FOUND") {
showMessage(...);
} else if(e.getErrorCode().equals("DUPLICATE_VALUE_FOUND") {
showMessage(...);
}
}
我建議使用Spring的JDBCTemplate
。 它將大多數現有數據庫的異常轉換為特定的未經檢查的異常,例如DataIntegrityViolationException
。 它還將在消息中包含原始SQL錯誤。
奇怪的問題,因為這兩種方法都做同樣的事情:它們將已檢查的SqlException轉換為另一個似乎未被檢查的異常。 因此,第一個是更好的方法,因為它將其轉移到一個方法中。
兩者都留下一些問題要問:
沒有一些可以進行此轉換的基礎結構(另一個答案中提到了Spring模板)
您是否真的要檢查異常,在我看來,它們幾乎不值得麻煩。
誰在真正地處理異常,異常是否獲得了所需的所有信息? 通常,我希望有關MyException內部失敗的事務的一些其他信息,例如:我們試圖做什么? (例如更新業務對象); 在什么樣的物體上? (例如一個人); 我們/用戶如何識別對象(例如person.id + person.lastname + person.firstname)。 如果您想產生日志/錯誤消息,而不是告訴您或您的用戶“糟糕,出問題了”,則需要此類信息。
為什么MyException是可變的(至少在第二個示例中)
比任何一個更好的設計都是通過擴展RuntimeException
使您的自定義異常不受檢查。
我希望您的異常包裝第一個異常,因此以這種方式進行編碼也將更好:
MyException exception = new MyException(e); // wrap it.
如果這樣做,則首選第二個。 更多信息更好。
恕我直言,這取決於您的代碼與SQL緊密耦合的程度。
如果該方法始終與SQL結合使用(* 1),我只需要聲明並重新拋出SQLException
(在清理/關閉資源之后)。 然后,可以識別SQL的高級方法將在其認為合適的情況下對其進行處理(也許他們需要所有詳細信息,也許不需要)。
如果將來某個時候可以將方法更改為另一個不使用SQL的方法,那么我將選擇第二種方法。
(1):對於這種假設要格外悲觀:“我認為我們不會改變”應該解釋為“可能我們會想要改變”。 “我們不會改變”是指“無論如何都不會破壞很多其他方法,我們就無法改變”。
一種差異將是您catch
異常的方式。 在第一種情況下,您可以catch
異常,並且知道錯誤是什么。 在第二種情況下,您必須catch
異常並檢查代碼以查看錯誤是什么。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.