2012-01-04 22 views
5

我目前用的MyBatis-Spring集成框架的工作,這就是我的文檔閱讀:MyBatis映射器直接注入服務類。例外情況如何?

而不是使用手動SqlSessionDaoSupport或SqlSessionTemplate, MyBatis的彈簧代碼數據訪問對象(DAO)提供代理工廠:MapperFactoryBean。這個類允許你將數據映射器接口 直接注入到你的服務bean中。使用映射器時,您只需調用它們,因爲您始終將其稱爲 DAO,但您不需要編寫任何DAO實現,因爲MyBatis-Spring將爲您創建 的代理。

這是一個非常不錯的功能......但什麼異常處理?我應該在哪裏翻譯SQL錯誤?在我的服務層?但是它不會違反服務-DAO模式嗎?

例子:

public final class AccountServiceImpl implements AccountService { 
(...) 
    private AccountMapper accountMapper; 
(...) 
    @Override 
    public void addAccount(Account account) throws AccountServiceException { 

     //Validating, processing, setting timestamps etc. 
     (...) 

     //Persistence: 
     int rowsAffected; 
     try { 
      rowsAffected = accountMapper.insertAccount(account); 
     } catch (Exception e) { 
      String msg = e.getMessage(); 
      if (msg.contains("accounts_pkey")) 
       throw new AccountServiceException("Username already exists!"); 
      if (msg.contains("accounts_email_key")) 
       throw new AccountServiceException("E-mail already exists!"); 
      throw new AccountServiceException(APP_ERROR); 
     } 

     LOG.debug("Rows affected: '{}'", rowsAffected); 

     if (rowsAffected != 1) 
      throw new AccountServiceException(APP_ERROR); 
    } 

是否確定翻譯服務層異常?

應該怎麼做?

在此先感謝您的建議。

回答

6

最近在一個項目中使用了mybatis-spring,我遇到了同樣的絆腳石。我也不想拋棄使用DAO異常處理的服務類,特別是因爲我的服務層中的某些方法需要對很多不同表進行只讀訪問。

我到是要趕在服務層中的異常,但創建自己的異常類型,是以捕獲的異常作爲參數的解決方案。然後,這可以過濾掉實際構造異常時應該包含哪種錯誤消息,並刪除對字符串匹配的需求(至少在服務層中)。

您接近那裏,除了AccountServiceException會有一個構造函數,它將Exception e作爲參數。我還選擇儘可能早地嘗試和完成所有數據訪問,並將其全部包裝在一個try/catch中。由於MapperFactoryBean總是將拋出的異常轉換爲Spring DataAccessExceptions,因此您不必擔心在執行數據訪問時捕獲其他類型的異常。

我毫不猶豫地認爲這是一個答案,因爲這樣的 - 更多的經驗分享給我遇到了這一點,猶豫也是如此。通過在MyBatis的服務層拋出到應用程序定義的那些

+0

非常好的答案!謝謝! – 2012-01-04 15:11:59

1

翻譯低電平的DataAccessExceptions是一個標準的做法。

它通常連接到事務處理,你不能處理中跨越DA層多個DAO交易。

所以是沒關係,甚至推薦。

通常我記錄由DAO錯誤日誌中拋出的異常,並重新拋出由應用程序定義的東西。