Рубрики
Без рубрики

Три шага для расширения репозитория Spring Data JPA с помощью вашего собственного кода

Это сообщение № 6 из серии “Запрос вашего хранилища JPA Spring Data”. Как насчет ан… С тегами spring, репозиторий, java, jpa.

Запрос вашего репозитория Spring Data JPA (серия из 6 частей)

Это сообщение № 6 из серии “Запрос вашего хранилища JPA Spring Data”.

Что делать, если вы хотите выполнить поиск по любому полю, доступному в ресторане, и объединить его, не выбирая конкретные запросы.

Ну, это не Google, но он достаточно мощный для многих случаев использования.

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

Форма поиска выглядит следующим образом:

Filter Restaurants

Нам нужны новые методы контроллера для обработки новой страницы и операции поиска:

@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 {
    List advancedSearch(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 List advancedSearch(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”