#spring #hibernate
#spring #спящий режим
Вопрос:
У меня реляционная (тяжелая) модель базы данных с большим количеством табличных зависимостей и внешних ключей. Мы решили использовать DTO, чтобы упростить представление данных спереди и скрыть соответствие режиму базы данных.
Но у нас есть DTO с вложенным DTO. И у нас есть классы реализации Mapper для установки данных с помощью небольшой бизнес- / функциональной логики.
Вопрос в том, является ли хорошей практикой, когда класс mapper вызывает mapper (и т. Д.), Или это лучший способ иметь основной класс, обрабатывающий все классы mapper? (Пример 1 или 2)
Пример 1 :
@Component
public class ActorMapperImpl implements ActorMapper {
@Autowired
private InsurerMapper insurerMapper;
@Autowired
private PersonMapper personMapper;
@Autowired
private CorrespondentMapper correspondentMapper;
....
@Override
public ActorDto mapToDto(Acteur actor) {
final ActorDto actorDto;
if (actor != null) {
....
actorDto.setPerson(personMapper.personneToPersonDto(actor.getPersonne()));
if (actor.getInsurer() != null) {
actorDto.setInsurer(insurerMapper.entityToDto(actor.getInsurer()));
} else if (actor.getCorrespondantAssureur() != null) {
actorDto.setInsurer(correspondentMapper.correspondentToInsurerDto(actor.getCorrespondantAssureur()));
}
....
// intermediate
final Intermediaire intermediate = actor.getIntermediaire();
if (intermediate != null) {
.....
if (person != null) {
intermediateDto = personMapper.personneToPersonDto(person);
intermediateDto.setQuality(quality);
}
.....
}
.....
Пример 2 :
@Service
public class FinancialSlipOrchestratorImpl implements FinancialSlipOrchestrator {
.....
@Autowired
private FinancialSlipMapper financialSlipMapper;
@Autowired
private PersonMapper personMapper;
..... some public / private methods
private FinancialSlipDto fullMapToDto(FinancialSlip financialSlip) {
.....
// Financial slip
var financialSlipDto = financialSlipMapper.mapToDto(financialSlip);
// person
financialSlipDto.setIssuerPerson(personMapper.personneToPersonDto(financialSlip.getIssuerPerson()));
....
// RIB
financialSlipDto.setRib(ribMapper.mapToDto(financialSlip.getRib()));
return financialSlipDto;
}
Комментарии:
1. Не уверен, что здесь лучше всего, но я бы выбрал ручную оркестровку. Таким образом, вы сохраняете контроль и не сталкиваетесь с риском циклических зависимостей.
Ответ №1:
Я бы сказал, что для одного картографа нормально вызывать другого и думать, что это идеальный вариант использования для представлений объектов с сохранением Блейза.
Я создал библиотеку, чтобы обеспечить простое сопоставление между моделями JPA и моделями, определяемыми пользовательским интерфейсом или абстрактным классом, что-то вроде проекций данных Spring на стероидах. Идея заключается в том, что вы определяете свою целевую структуру (модель домена) так, как вам нравится, и сопоставляете атрибуты (геттеры) с помощью выражений JPQL с моделью сущности.
Модель DTO для вашего варианта использования может выглядеть следующим образом с помощью представлений объектов Blaze-Persistence:
@EntityView(Acteur.class)
public interface ActorDto {
@IdMapping
Long getId();
String getName();
PersonDto getPerson();
default InsurerDto getInsurer() {
return getMainInsurer() != null ? getMainInsurer(): getCorrespondantAssureur();
}
@Mapping("insurer")
InsurerDto getMainInsurer();
InsurerDto getCorrespondantAssureur();
IntermediaireDto getIntermediaire();
@EntityView(Person.class)
interface PersonDto {
@IdMapping
Long getId();
String getName();
}
@EntityView(Insurer.class)
interface InsurerDto {
@IdMapping
Long getId();
String getName();
}
@EntityView(Intermediaire.class)
interface IntermediaireDto {
@IdMapping
Long getId();
String getName();
Integer getQuality();
PersonDto getPerson();
}
}
Запрос — это вопрос применения представления сущности к запросу, простейшим из которых является просто запрос по идентификатору.
ActorDto a = entityViewManager.find(entityManager, ActorDto.class, id);
Интеграция данных Spring позволяет использовать его почти как проекции данных Spring: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features
Самое лучшее в этом то, что он будет извлекать только те данные, которые действительно необходимы.
Если вы также используете DTO для возврата изменений, вы будете рады услышать, что Blaze-Persistence Entity-Views также поддерживает это очень эффективным образом. Это позволит вам избавиться от всех этих написанных вручную картографов 🙂
Комментарии:
1. Спасибо за ответ