Я начинаю весну Jpa. У меня возникает ошибка. Я хочу знать, каковы преимущества и недостатки:
- Обращайтесь со всем бизнесом в классе Service и многократно звоните в Jpa Repository, который содержит только базовые операции, такие как CRUD, getList ....
Vs
- Сделайте длинный запрос @Query
в Jpa Repository.Spring Jpa Service вызывает vs Jpa query
ответ
Как правило, вам всегда нужно вызывать репозиторий JPA с одним запросом, только для выбора объектов, которые необходимо изменить. Затем вы можете загружать данные и изменять извлеченные объекты напрямую, используя свои методы. Данные, которые не были загружены запросом, будут загружаться автоматически, когда объект им нужен.
Например, вы можете загрузить человека и изменить его контактный адрес, как это:
Person person = personRepository.find(personId);
for (Address address : person.getAddresses()) {
if ("CONTACT_ADDRESS".equals(address.getType()) {
address.setCity("London");
}
}
Все необходимые данные извлекаются и все изменения, сохраняются в БД.
Хотя это легко и просто, иногда могут возникать проблемы с производительностью, особенно если вам нужно загрузить только один адрес, а не все адреса. Или, если вам всегда нужны все адреса и вы хотите загрузить их в одном запросе вместе с человеком.
Тогда это хорошее решение для внедрения нового оптимизированного запроса в репозиторий. Например, запрос, который будет загружать все адреса с fetch join
и не требует дополнительного ленивого (автоматический) запроса для загрузки их, когда вы перебирать адреса:
@Query("select distinct u from User u left join fetch u.addresses where u.id = ?")
public List<User> findWithAddresses(Long id);
Это не потребует, чтобы изменить код выше, кроме для переключения метода find()
для findWithAddresses()
. Но в фоновом режиме будет выполняться только один SQL-запрос вместо нескольких SQL-запросов.
Да! это то, что я ищу. Кстати, знаете ли вы, когда соединение с базой данных заимствовано из пула соединений? Когда он отпустит соединение? –
Соединение обычно назначается во время транзакции, поэтому оно «заимствовано» при запуске транзакции и освобождается при фиксации или откате. Но я не уверен, что это конкретная реализация, и возможно, что entitymanager поддерживает назначенное соединение до закрытия, но это было бы довольно глупо. – OndrejM
- 1. JPA: find() vs query
- 2. Spring JPA Data «OR» query
- 3. Spring JPA @Query с LIKE
- 4. Spring JPA @Query с выражением
- 5. Spring JPA deleteInBatch вызывает StackOverflow
- 6. Spring JPA Query возвращает Null вместо списка
- 7. JPA flush vs commit
- 8. JPA Repository - Query
- 9. JPA Eclipselink NamedQuery vs Query COUNT
- 10. JPA Native Query отображение
- 11. Spring Data JPA @Query аннотаций, nativeQuery = правда,
- 12. spring data jpa native query with join
- 13. Spring Data (JPA) - использование дженериков в @Query
- 14. Spring Data JPA Update @Query не обновляется?
- 15. Spring Boot JPA Query for not null
- 16. Spring JPA
- 17. Spring DATA JPA Rest
- 18. jpa: репозитории/@EnableJpaRepositories vs @Repository - spring
- 19. Spring, JPA, Hibernate 3 vs 4
- 20. Счетчик JPA-репозиториев Spring
- 21. Spring Загрузочного JPA CrudRepository
- 22. Spring-Data-JPA paging
- 23. Spring Data JPA PropertyReferenceException?
- 24. Spring Data JPA SubQuery
- 25. Spring JPA Data's Repository
- 26. Рекомендации - SPRING JPA JoinColumns
- 27. JPA 2.0 Sub select in JPA query query
- 28. JPA Query - sql injection в позиционных параметрах jpa native query
- 29. Spring + JPA/Hibernate вопросы
- 30. Ошибка автоподатчика Spring JPA
Первый не имеет смысла. У пользователя уже есть адреса, и все, что вам нужно получить к ним, это вызвать 'user.getAddresses()'. Второй тоже не имеет большого смысла. Левое соединение в запросе совершенно бесполезно. Если вы хотите, чтобы этот запрос загружал пользователя с его адресами в одном запросе (и не полагался на ленивую загрузку для получения адресов), тогда запрос должен быть 'select different u из User u left join fetch u.addresses, где u .id =: id'. –
Во-первых, что, если это ленивая нагрузка? Я не могу получить адреса, вызвав 'user.getAddresses()'. И зачем мне здесь «особенный»? Весь список отличается. Пропустите пример, вопрос в том, что в моем примере это то же самое, я имею в виду количество раз, когда он открывает соединение с базой данных, количество запросов и прокси-доступа. –
Lazy-loading не означает, что «адреса никогда не будут загружены». Это означает, что «адреса будут загружены, когда они вам понадобятся». Так что да, вызывая, например, user.getAddresses(). Size() будет выполнять дополнительный запрос для загрузки адресов, заполнения списка адресов пользователя и последующего возврата количества адресов пользователя. Разница нужна, потому что в противном случае вы получите список из 3 пользователей, если у пользователя есть 3 адреса, а не список из 1 пользователя. –