Запрос вашего репозитория Spring Data JPA (серия из 6 частей)
Это сообщение № 6 из серии “Запрос вашего хранилища JPA Spring Data”.
Что делать, если вы хотите выполнить поиск по любому полю, доступному в ресторане, и объединить его, не выбирая конкретные запросы.
Ну, это не Google, но он достаточно мощный для многих случаев использования.
Ну, ты же знаешь, как это делается. Давайте создадим то, что необходимо для работы приложения с этой новой опцией расширенного поиска.
Форма поиска выглядит следующим образом:
Нам нужны новые методы контроллера для обработки новой страницы и операции поиска:
@RequestMapping("/advancedSearch") public String advancedSearch(Model model) { model.addAttribute("restaurants", restaurantRepository.findAll()); model.addAttribute("search", new AdvancedSearch()); return "advancedSearch"; } @RequestMapping("/advancedSearch/perform") public String advancedSearchWithQuery(@ModelAttribute AdvancedSearch advancedSearch, Model model) { model.addAttribute("restaurants", restaurantRepository.advancedSearch(advancedSearch)); model.addAttribute("search", advancedSearch); return "advancedSearch"; }
Следите за:
- Атрибут
@ModelAttribute
аннотация: он отображает входные данные в новый класс, называемый… Расширенный поиск
. Это простой компонент с полями для хранения данных, поступающих из формы. С помощью Проекта Ломбок этот класс довольно прост .- Мы используем этот класс для передачи данных между формой и приложением в обоих направлениях. Именно так мы можем показывать вводимые пользователем запросы даже после обновления страницы, чтобы показать результаты поиска (помните, что это не ваш типичный SPA, хорошо?).
Но вы, возможно, также заметили, что мы вызываем новый метод на Ресторанрепозиция
вызывается расширенный поиск
передача омонима расширенный поиск
объект через параметр. Нет, это не метод Spring Data JPA по умолчанию (было бы неплохо, ха?), Но возможность создавать свои собственные методы – это мощный материал, который мы здесь изучаем!
Давайте посмотрим, как в 3 шага.
Шаг 1. Создайте новый интерфейс для хранения объявлений методов
public interface CustomRestaurantRepository { ListadvancedSearch(AdvancedSearch advancedSearch); }
Обратите внимание на определение метода расширенный поиск
. Это все, что нам сейчас нужно.
Шаг 2: Сделайте свой репозиторий Spring Data JPA расширяющим ваш новый интерфейс
public interface RestaurantRepository extends JpaRepository, CustomRestaurantRepository {
Теперь обратите внимание, что наш репозиторий расширяет оба JpaRepository
((из проекта Spring Data JPA) и Пользовательский каталог ресторанов
(собственный класс для определения методов репозитория). Теперь мы можем вызвать наш новый метод, но как насчет его кода?
Шаг 3: Реализуйте пользовательский метод
Теперь это просто вопрос реализации кода, который нам нужен. Мы создадим Пользовательский репозиторий ресторана
класс, который реализует наш недавно созданный Пользовательский интерфейс
.
@Repository public class CustomRestaurantRepositoryImpl implements CustomRestaurantRepository { @PersistenceContext private EntityManager entityManager; @Override public ListadvancedSearch(AdvancedSearch advancedSearch) { var jpql = new StringBuilder(); jpql.append("from Restaurant where 1=1 "); var parameters = new HashMap (); if (StringUtils.hasLength(advancedSearch.getName())) { jpql.append("and name like :name "); parameters.put("name", "%" + advancedSearch.getName() + "%"); } if (StringUtils.hasLength(advancedSearch.getAddress())) { jpql.append("and address like :address "); parameters.put("address", "%" + advancedSearch.getAddress() + "%"); } if (advancedSearch.getMinDeliveryFee() != null) { jpql.append("and deliveryFee >= :startFee "); parameters.put("startFee", advancedSearch.getMinDeliveryFee()); } if (advancedSearch.getMaxDeliveryFee() != null) { jpql.append("and deliveryFee <= :endingFee "); parameters.put("endingFee", advancedSearch.getMaxDeliveryFee()); } if (StringUtils.hasLength(advancedSearch.getCuisine())) { jpql.append("and cuisine.name like :cuisine "); parameters.put("cuisine", "%" + advancedSearch.getCuisine() + "%"); } if (StringUtils.hasLength(advancedSearch.getCity())) { jpql.append("and city like :city "); parameters.put("city", "%" + advancedSearch.getCity() + "%"); } TypedQuery query = entityManager.createQuery(jpql.toString(), Restaurant.class); parameters.forEach((key, value) -> query.setParameter(key, value)); return query.getResultList(); } }
Здесь многое нужно распаковать:
- Во-первых, мы получаем доступ к
Менеджер сущностей
вводим его через@PersistenceContext
. С помощью этого мы можем выполнять операции через JPA. Затем мы переопределяем метод
AdvancedSearch
, чтобы:- Проверьте каждое свойство объекта
Расширенный поиск
, добавив его, если оно не равно нулю, в пользовательский запрос JPQL. - Соответствуют соответствующим параметрам. Сначала на временной карте, а затем на фактическом отображении в запросе.
- Выполните запрос, возвращающий результаты.
- Проверьте каждое свойство объекта
- И последнее, но не менее важное: суффикс
Impl
это то, что на самом деле говорит Spring Data JPA, что это пользовательская реализация существующегоРесторан-ресторан
. Добавление нашего интерфейса и расширение интерфейса Spring Data JPA предназначено только для того, чтобы сделать код читаемым. Ты должен это сделать!
Обратите внимание, что в примере приложения также есть возможность выбрать логический оператор для использования при выполнении расширенного поиска, И
или ИЛИ
. Возможно, вы захотите попробовать реализовать это самостоятельно, но если вы этого не хотите, вот реализация для вас.
Это окончательный результат:
Рабочее приложение находится здесь (подождите, пока Heroku загрузит приложение, на бесплатном уровне это займет несколько секунд).
Подготовка и основной код находятся здесь . Логическим оператором добавления является здесь . И есть улучшение пользовательского интерфейса, которое я сделал здесь
брунодруговик/jpa-запросы-запись в блоге
Демонстрационный проект для сообщения в блоге о (весенних данных) JPA.
Запрос вашего репозитория Spring Data JPA (серия из 6 частей)
Оригинал: “https://dev.to/brunodrugowick/four-steps-to-extend-a-spring-data-jpa-repository-with-your-own-code-53b0”