#java #spring #hibernate
#java #spring #переход в спящий режим
Вопрос:
Привет, ребята, я новичок в Spring.Просто возникли сомнения .Классы service и DAO выполняют одно и то же? Зачем вам нужны они оба? Кроме того, мы можем подключить наш контроллер напрямую к нашим методам Dao и извлекать из них данные. В чем именно заключается потребность в сервисном уровне. Я прошел через несколько порталов, некоторые из которых сообщили, что service layer обеспечивает модульность, и немногие из них упомянули, что это также в целях безопасности. Я все еще в замешательстве, может ли кто-нибудь дать четкий ответ на этот запрос?
Комментарии:
1. Все, что не соответствует SQL explicilty — безопасность, проверка входных данных, ведение журнала, «бизнес-логика», прежде всего, — должно быть перенесено на уровень сервиса.
Ответ №1:
Уровень сервиса необходим в случае транзакции и отката. предположим, в одном случае у вас есть один метод, который выполняет многократное обновление или delete.in в таком случае ваш контроллер может не поддерживать транзакцию, но на уровне сервиса spring предоставляет вам способ фиксации и отката
Наличие сервисного уровня в качестве оболочки вокруг DAO является распространенным антишаблоном. В примере, который вы приводите, это, конечно, не очень полезно. Использование уровня сервиса означает, что вы получаете несколько преимуществ:
вы можете провести четкое различие между действиями веб-типа, которые лучше всего выполнять в контроллере, и общей бизнес-логикой, которая не связана с Интернетом. Вы можете тестировать бизнес-логику, связанную с сервисом, отдельно от логики контроллера.
- вы можете указать поведение транзакции, поэтому, если у вас есть вызовы к нескольким объектам доступа к данным
- вы можете указать, что они происходят в рамках одной транзакции
- вы можете вложить сервисы так, чтобы, если у одного из них другое поведение при транзакциях (требуется его собственная транзакция), вы могли обеспечить это.
- вы можете использовать перехватчик postCommit для выполнения уведомлений, таких как отправка электронных писем, чтобы это не приводило к перегрузке контроллера.
Обычно у меня есть сервисы, которые охватывают варианты использования для одного типа пользователей, каждый метод в сервисе представляет собой одно действие (работа, выполняемая за один цикл запрос-ответ), которое будет выполнять этот пользователь, и в отличие от вашего примера, обычно там происходит нечто большее, чем простой вызов объекта доступа к данным.
Ответ №2:
Цель service layer — использовать DAO (ы) для реализации вашей бизнес-логики. Я перечислил несколько преимуществ уровня сервиса ниже
-
Уровень сервиса может использовать транзакции для выполнения атомарных операций.Использование транзакции на уровне DAO не создает sens (для сложного варианта использования), поскольку в операции может быть задействовано несколько объектов.
-
С помощью Service Layer мы можем расширить область действия сеанса до запроса вместо сеанса для каждой операции.
-
Уровень сервиса может использоваться для обработки исключения, специфичного для бизнеса, и может генерировать новое бизнес-исключение, которое может использоваться для отображения страницы ошибки. Выдача специфичных для бизнеса исключений, таких как BadCredentials или InvalidInput из DAO, добавляет DAO дополнительную ответственность за проверку имени пользователя и пароля. В идеале DAO предназначен только для связи с базой данных, и вся бизнес-логика должна находиться на уровне сервиса.
-
Один сервис может использовать несколько сервисов для выполнения рабочего процесса и позволяет повторно использовать код.
например, вариант использования
Это простая реализация DAO, которая может завершиться сбоем при одновременном доступе к одной и той же строке базы данных. Предположим, что существуют две операции A и B. Операции A и B хотят создать пользователя с одинаковым именем пользователя, если его еще нет.
Запускается операция A — > getUser(«abc») возвращает null —> следовательно, CreateUser(abc).
Запускается операция B —> getUser(«abc») возвращает null, поскольку транзакция A еще не создала пользователя abc—> следовательно, CreateUser(abc), это вызовет либо исключение базы данных для дублирующего первичного ключа, если мы используем username в качестве первичного ключа, либо у нас могут быть два пользователя с одинаковым именем пользователя, если мы используем суррогатный ключ, поскольку операция A создала пользователя abc в предыдущей транзакции.
public class UserDao{
public User getUser(String Username){
User user = null;
Session session = SessionFactory.OpenSession();
Transaction tx = session.beginTransaction();
// Some logic here...//
tx.commit();
session.close();
retur user;
}
public User createUser(User user){
Session session = SessionFactory.OpenSession();
Transaction tx = session.beginTransaction();
// Some logic here...//
tx.commit();
session.close();
}
}
public class NewUserDao{
public User getUser(String Username){
User user = null;
Session session = SessionFactory.getCurrentSession();
// Some logic here...//
return user;
}
public User createUser(User user){
Session session = SessionFactory.getCurrentSession();
// Some logic here...//
return user;
}
}
public class UserService{
New UserDao newUserDao; //Dependecy injection
@Transactional
public User createUser(User user){
if(newUserDao.getUser(user.getUserName())== null){
newUserDao.createUser(user);
}
}
}
Ответ №3:
Вы должны поместить в DAO весь доступ к базе данных, и вы не должны помещать сюда бизнес-логику. Вся логика должна идти в сервисы, и сервисы должны вызывать DAO для выполнения запросов к базе данных.