Какова связь между DTO и отложенной загрузкой в ​​Hibernate? - PullRequest
0 голосов
/ 22 ноября 2018

Я знаю, что такое DTO: объект, который переносит данные между процессами, чтобы уменьшить количество вызовов методов.и я знаю, что такое отложенная загрузка в hibernate.

Я читал следующие предложения в книге «Разработка полного стека с помощью JHipster»: JHipster использует DTO (Data Transfer Object) и VM (View Model) на стороне сервера.DTO предназначены для передачи данных с уровня обслуживания на уровень ресурсов и обратно.Они нарушают транзакции Hibernate и предотвращают дальнейшую отложенную загрузку от уровня ресурсов.

Я не понимаю взаимосвязи между DTO и отложенной загрузкой.

Ответы [ 3 ]

0 голосов
/ 22 ноября 2018

Проще говоря: если вы вызываете метод получения поля с отложенной загрузкой, Hibernate сделает запрос БД для этих данных.

Это одна из причин, по которой вы не должны возвращать сущности в качестве ответа бэкэнда ... любой вызов преобразования JSON (сериализации) / геттера вызовет нежелательную загрузку данных.

, тогда как DTO являетсясделано специально для передачи данных по мере использования, и вы создаете DTO из этих сущностей (из одной сущности можно создать несколько DTO) и выбираете только обязательные поля данных

Например. Пользовательская сущность: есть пользовательподробности и список друзей UserDetailsDTO: потребуются только детали и не нужны 1000 друзей, сопоставленных с пользователем ... и их друзьями ... UserFriendsDTO: мы можем выборочно получать имена или идентификаторы друзей для этого DTO

0 голосов
/ 28 ноября 2018

Ленивая загрузка предназначена для организаций, а не DTO.

Сущность JPA может быть представлена ​​как POJO или Proxy .

Как я объяснил в этой статье , использование EntityManager.find дает вамPOJO:

Post post = entityManager.find(Post.class, postId);

В то время как метод EtityManager.getReference предоставляет вам прокси:

Post post = entityManager.getReference(Post.class, postId);

POJO имеет свои базовые свойства, инициализированные, потому что инструкция SELECT была выполнена для извлечения сущности.Прокси не попадает в базу данных при создании.Только идентификатор устанавливается на основе предоставленного идентификатора объекта.Только вы обращаетесь к свойствам Proxy, будет выполняться оператор SELECT.

Прокси также используются для коллекций (например, @OneToMany или @ManyToMany), которые по умолчанию используют стратегию FetchType.LAZY.Как только вы получите доступ к коллекции LAZY, будет выполнен оператор SELECT для извлечения связанной коллекции.

Теперь DTO основан на проекции, следовательно, оператор SELECT выполняется до заполнения DTO.Для этого вы можете сказать, что DTO загружается каждый раз.

DTO гораздо эффективнее, чем объекты для проекций только для чтения, потому что вы загружаете только те столбцы таблицы, которые вы явно запросили.Подробнее о том, как лучше использовать DTO с JPA и Hibernate, читайте в этой статье .

0 голосов
/ 22 ноября 2018

Если вы передадите управляемые постоянные объекты Hibernate на уровень ресурсов с включенным LazyLoading, уровень ресурсов будет вызывать get -методы, чтобы прочитать их свойства, некоторые из которых, возможно, не были инициализированы в это время.Затем Hibernate будет лениво загружать данные этого конкретного свойства из хранилища persisntet, отправляя оператор SQL (возможно, каждый раз при запуске и совершении новой транзакции) и ожидая ответа, который довольно медленный.Если это происходит сотни раз, каждый раз, когда нужно инициализировать другое свойство, каждый раз вызывая ленивую загрузку, пользователь должен ждать ...

Если вы подготавливаете DTO на своем сервисном уровне, содержащем все данныеОтносительно уровня ресурсов, доступ для чтения к этому DTO очень эффективен без риска попадания в базу данных при любом вызове get -метода, поскольку все релевантное уже находится в памяти.Последующая отложенная загрузка не будет запущена.

...