Классы Service и DAO делают одно и то же. Зачем вам нужны они оба?

#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 для выполнения запросов к базе данных.