MyBatis映射器直接注入服务类.例外呢?

Mac*_*rko 6 java spring dao design-patterns mybatis

我目前正在使用MyBatis-Spring集成框架,这就是我从docs中读到的内容:

Mybatis-Spring不是使用SqlSessionDaoSupport或SqlSessionTemplate手动编写数据访问对象(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);
    }
Run Code Online (Sandbox Code Playgroud)

在服务层中转换异常是否可以?

应该怎么做?

在此先感谢您的建议.

BeR*_*ive 7

最近我使用了mybatis-spring进行了一个项目,我遇到了同样的绊脚石.我也不想在DAO异常处理中丢弃我的服务类,特别是因为我的服务层中的某些方法需要对许多不同的表进行只读访问.

我得到的解决方案是捕获服务层中的异常,但创建自己的异常类型,将捕获的异常作为参数.然后,这可以过滤掉实际构造异常时应包含的错误消息类型,并消除对字符串匹配的需要(至少在服务层中).

你接近那里,除了AccountServiceException将有一个构造函数Exception e作为参数.我还选择尽早尝试进行所有数据访问,并将其全部包含在一个try/catch中.由于MapperFactoryBean始终将抛出的异常转换为Spring DataAccessExceptions,因此在进行数据访问时不必担心捕获其他类型的异常.

我毫不犹豫地认为这是一个答案 - 更多的是经验分享,因为我遇到了这个问题并且犹豫不决.