Service - DAO pattern, DTO и реляционная база данных



Во-первых, я сожалею, если эта тема уже рассматривалась, но я не нашел того, что искал.
Я работаю над ERP, и мы пытаемся сделать некоторый рефакторинг кода. Основная проблема заключается в том, что в настоящее время мы не используем никакой шаблон DAO, что может стать проблемой в будущем, если нам потребуется получить доступ к "базе данных" по-другому.



Короче говоря, наша архитектура будет стремиться к этому образцу:



Bean или Webservices называют то, что мы называем "транзакционным уровнем" (инкапсулирует сервисы так, что некоторые вещи могут быть представлены через WS и делать другие вещи). Этот слой вызывает службы, которые будут вызывать другие службы или DAOs.



1) сущность



public class MyObject{
private String arg1;
private List<SomeOtherObject> arg2List;

}


2) Дао



public interface MyObjectDAO {
void save();
List<MyObject> findAllObjects();
// Some other queries
// ...
}


3) MyObjectService



@Service
public class MyObjectService{
@Autowired
MyObjectDAO dao;

@Autowired
MyOtherObjectDAO otherDao;

public void createObject(String arg1Dto, List<MyOtherObjectDto> arg2Dto){
// How to deal with arg 2 ?


MyObject obj = new MyObject();
obj.setArg1(arg1);
obj.setArg2(myEntityRepresentingArg2);
dao.save(obj1);
}
}


3) Уровень Транзакций



public class{
// Many many things...

//Method called from the Beans
@Transactional(rollbackFor=Exception.class)
public void serviceCall(SomeDto arguments){
myObjectServices.createObject(arguments.getArg1(), arguments.getArg2());
}
}


Мой вопрос касается лучших практик:





  • Прежде всего, мы используем Hibernate и JPARepository для управления сущностями. Итак, я предполагаю, что вызов репозиториев должен быть выполнен в DAOImpls ? Как насчет запросов, которые мы делаем к базе данных (то есть JPAQuery с соединениями, selects и т. д.) и делаем прогнозы ? Таким образом, Дао вернет DTOs...



  • Мы также не уверены, где использовать DTOs. Где должна быть граница между использованием DTO в "транзакционном слое" и сущностями в DAOs ? Следует ли передать DTO классам обслуживания, а затем полностью передать сущности на уровень DAO ? Или мы должны передавать только аргументы Дао, и оно создает сами сущности (проблема в том, что это приводит к некоторым огромным сигнатурам метода).



Большое вам спасибо и не стесняйтесь задавать вопросы, если это необходимо !

877   2  

2 ответов:

  • где использовать DTOs?

Обычно сервисный метод получает DTO в качестве параметра и внутри своей реализации этот DTO преобразуется/сопоставляется в сущность, которая передается в репозиторий.

Репозитории (или DAOs) должны знать только о сущностях, а не о DTO, а другие слои должны знать только о DTO, а не о сущностях.

Чтобы подвести итог, классы обслуживания должны принимать и возвращать только DTOs. Это делается для того, чтобы скрыть модель и ее детали за пределами слой персистентности. Пример:

public class ProjectService {
    // The Repository should be an interface and Spring injects your Impl
    @Autowired
    private ProjectRepository projectRepository;

    public void createProject(ProjectDto dto) {
        // We map the Dto into an Entity
        Project project = new Project();
        project.setName(dto.getName);
        project.setDepartment(dto.getDepartment);        

        projectRepository.save(project);
    }

    public ProjectDto findProject(Long id) {
        // Get Project entity
        Project project = projectRepository.findOne(id);
        // Map entity to dto
        ProjectDto dto = new ProjectDto();
        dto.setName(project.getName());
        dto.setDepartment(project.getDepartment());

        return dto;
    }
}

Как вы видите, будет много шаблонных схем для отображения сущностей в dto и viceversa. Вы можете инкапсулировать его в методы, которые просто сделают преобразование или даже лучше, вы можете использовать библиотеку отображения, такую какOrika илиDozer .

Вот пример того, как использовать Orika и интегрировать его с Spring, если вам это нужно.

  • о репозиториях DAOs и JPA

Если вы используете Spring Data JPA repositories вам не нужен никакой DAO, вам просто нужен интерфейс для репозитория и, возможно, реализация для этого интерфейса. Если вы хотите, вы можете иметь DAOs и использовать их в реализации репозитория, но в этом нет необходимости. У них есть хорошие примеры на их справочной документации .

Для выполнения SQL-запросов можно использовать @Query. Он может принимать запросы JPQL или native SQL, когда nativeQuery=true. Вы можете найти дополнительную информацию здесь .

  @Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?0", nativeQuery = true)
  User findByEmailAddress(String emailAddress);
Надеюсь, это помогло.

Когда данные пересекают "уровень обслуживания / транзакции", вы определенно должны использовать шаблон DTO. Я написал статью о некоторых общих проблемах, которые возникают, когда этого не делается, а также о том, как можно эффективно реализовать подход DTO с представлениями сущностей Blaze-Persistence.

Может быть, вы хотите попробовать это вместо Orika или Dozer, так как это также улучшит производительность ваших запросов.

Если у вас есть репозитории Spring Data JPA, вы не должны больше не требуется отдельного Дао.

Comments

    Ничего не найдено.