Может ли уровень контроллера вызывать напрямую из уровня персистентности?

У меня есть веб-приложение с JSF, Spring и Mybatis. Эти фреймворки используются соответственно на уровне контроллеров, бизнеса и дао. На моем уровне DAO у меня есть методы для операций CRUD. Теперь в моем слое контроллера мне нужно использовать операцию вставки. Для этого я мог бы использовать эту конфигурацию:

Уровень контроллера

Я использую JSF с аннотациями

@ManagedBean
public class Controller{
    @ManagedProperty("#{business}")
    private Business business;

    public void insert(){
        business.insert();
    }
}

Бизнес уровень

Я использую Spring с аннотациями

public interface Business{
    public void insert();
}

@Service("business")
public class BusinessImpl implements Business{
    @Autowired
    private DaoMapper mapper;

    @Override
    @Transactional
    public void insert(){
        mapper.insert();
    }
}

Слой DAO

Я использую Mybatis (библиотека mybatis-spring)

public interface DaoMapper{
    public void insert();
}

Но так как в этом случае мой бизнес-уровень вызывает только уровень DAO и не выполняет никаких других операций, я бы подумал об использовании этой конфигурации:

Уровень контроллера

@ManagedBean
public class Controller{
    @ManagedProperty("#{daoMapper}")
    private DaoMapper mapper;

    public void insert(){
        mapper.insert();
    }
}

Слой DAO

public interface DaoMapper{

    @Transactional
    public void insert();
}

Я уже проверил и отлично работает, но я хотел бы знать, если я получаю плохую практику

[РЕДАКТИРОВАТЬ]

На самом деле интерфейс DaoMapper - это средство отображения классов MyBatis, которое связано с файлом XML ( взгляд). Я не знаю, делает ли это класс DAO. Я думаю, что на самом деле я должен называть это слой персистенции или слой картографа

Источник: http://www.infoq.com/articles/ddd-in-practice

Как вы видете. Уровень представления, в моем случае уровень контроллера (я думаю, я допустил еще одну ошибку при именовании), вызовите напрямую к DTO (или это то, что я понимаю)

Если в моем контроллере или на уровне представления (как бы вы это ни называли) мне нужно использовать операцию вставки или обновления, я мог бы вызывать напрямую из класса mapper, или мне обязательно нужно создать бизнес-класс для новых вызовов из этого класса в класс mapper.

Сейчас. Если возможно использовать эту конфигурацию, у меня есть сомнения:

Предположим, что в методе моего бизнес-класса мне нужно вызвать операцию вставки. Это было бы как:

@Service("business")
public class BusinessImpl implements Business{
    @Autowired
    private DaoMapper mapper;

    @Override
    @Transactional
    public void insert(){
        mapper.insert();
    }
}

Но метод вставки из интерфейса DaoMapper уже имеет аннотацию @Transactional. Вставка метода будет затронута дважды аннотацией @Transactional. Не будет ли это проблемой?

3 ответа

Решение

Я предлагаю не использовать DAO в контроллере напрямую. По моему мнению. Слой Dao - это отображение из базы данных, например, если вы хотите изменить другую базу данных (например, с sql на nosql), единственное, что нужно - это только создать новый DAO и внедрить его, но оставить функции контроллера и службы вообще не измененными. Так же как и контроллер, его основная ответственность заключается в обработке запросов и ответов, работа должна выполняться на уровне бизнеса / услуг. Если это неправильно, оцените

Если вы хотите удалить слои, вы можете использовать Controller и Service, но пропустите DAO. Ваша служба может напрямую вызывать маппер, поскольку у вас нет какого-либо конкретного кода запроса. Я знаю, что некоторые известные Java-люди, такие как Адам Бьен, считают DAO мертвым паттерном. http://www.adam-bien.com/roller/abien/entry/jpa_ejb3_killed_the_dao

Уровень обслуживания определяет действия вашей модели предметной области (бизнес-логику) и их атомарность.

Я предлагаю в любом случае иметь уровень обслуживания. У него важная функция. Он реализует «глаголы» / действия вашей модели предметной области, и это хорошее место, где вы также можете определить атомарность операций с помощью. На мой взгляд, аннотировать методы MyBatis mapper с помощью @Transactional. Сущности (POJO результата MyBatis в вашем случае) - это «существительные» вашей модели предметной области.

Модель предметной области без действий бесполезна.

Модель предметной области, состоящая только из «существительных», бесполезна, вы должны иметь возможность выполнять какие-то действия против нее («глаголы»). «Глаголы» реализуются служебным уровнем. Поэтому я считаю, что сервисный уровень необходим в 99,9% случаев. К настоящему времени вы столкнулись только с простыми случаями, когда действие бизнес-логики 1:1 для операции CRUD. Но это разные вещи. Могут быть и более сложные случаи. Представьте себе приложение онлайн-банкинга, в котором у вас есть вариант регистрации нового клиента. Это действие бизнес-логики, которое включает в себя несколько сущностей: вам нужно создать пользователя и вам нужно создать банковский счет, связанный с этим пользователем. И это должно происходить в одной транзакции SQL. Разделение «глагол» - «существительное» - вполне естественный подход.

Контроллеры обрабатывают веб-аспекты, они не предназначены для реализации действий модели предметной области.

Контроллеры - это контроллеры веб-страниц или контроллеры REST. Они обрабатывают аспекты, связанные с моделью страницы ( @ManagedBean в случае JSF) или определите RESTful API ( @RestControllerв случае Spring WebMVC). Они не предназначены для реализации действий модели предметной области. Также по этой причине использование сущностей в качестве DTO RESTful API также является плохой практикой. Сущности - это «существительные» модели предметной области, DTO RESTful API определяют представления для уровня RESTful API. Это разные вещи.

Другие вопросы по тегам