Может ли уровень контроллера вызывать напрямую из уровня персистентности?
У меня есть веб-приложение с 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. Это разные вещи.