MyBatis Mapper вводится непосредственно в класс обслуживания. Как насчет исключений? - PullRequest
6 голосов
/ 04 января 2012

В настоящее время я работаю с инфраструктурой интеграции MyBatis-Spring, и вот что я прочитал из документов:

Вместо того, чтобы кодировать объекты доступа к данным (DAO) вручную, используя SqlSessionDaoSupport или SqlSessionTemplate, Mybatis-Spring предоставляетфабрика прокси: MapperFactoryBean.Этот класс позволяет вам внедрять интерфейсы отображения данных непосредственно в ваши сервисные компоненты.При использовании картографов вы просто вызываете их, как вы всегда называли ваши 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);
    }

Можно ли переводить исключения на уровне сервиса?

Как это сделать?

Заранее спасибо за совет.

Ответы [ 2 ]

7 голосов
/ 04 января 2012

Недавно использовав mybatis-spring для проекта, я наткнулся на тот же камень преткновения. Я также не хотел засорять свой класс обслуживания обработкой исключений DAO, особенно потому, что некоторым методам в моем уровне обслуживания требовался доступ только для чтения к множеству различных таблиц.

Решение, к которому я пришел, заключалось в том, чтобы перехватывать исключения на уровне службы, но создавать собственный тип исключения, который принимает перехваченное исключение в качестве параметра. Затем можно отфильтровать, какое сообщение об ошибке должно содержаться при фактическом создании исключения, и устранить необходимость сопоставления строк (по крайней мере, на уровне службы).

Вы близки к этому, за исключением того, что AccountServiceException будет иметь конструктор, который принимает Exception e в качестве параметра. Я также решил попытаться сделать все свои данные доступными как можно раньше и обернуть все в одну попытку. Поскольку MapperFactoryBean всегда переводит выданные исключения в Spring DataAccessExceptions, вам не нужно беспокоиться о перехвате других видов исключений при доступе к данным.

Я не решаюсь считать это ответом как таковым - это скорее обмен опытом, учитывая, что я с этим сталкивался и колебался.

2 голосов
/ 04 января 2012

Преобразование низкоуровневых исключений DataAccessException, генерируемых MyBatis, в определяемые приложением на уровне обслуживания является стандартной практикой.

Обычно это связано с обработкой транзакций, поскольку вы не можете обработать транзакцию, охватывающую несколько DAO на уровне DA.

Так что да, это нормально и даже рекомендуется.

Обычно я записываю исключения, выданные DAO, в журнал ошибок и перебрасываю что-то, определенное приложением.

...