Статьи
Утилиты Telegram YouTube Отзывы

Spring Data JPA, REST и Kotlin: поиск записей

Видеогайд Исходники

15 марта 2023

Тэги: Kotlin, PostgreSQL, rest, Spring Boot, Spring Data, YouTube, руководство.

Содержание

  1. Поиск по id
  2. Поиск по имени

В предыдущей статье Spring Data JPA, REST и Kotlin: подключение к БД мы рассмотрели как можно подгружать из БД список всех стран, отсортированных по алфавиту и как реализовать постраничный вывод. А в данной статье узнаем, как искать страну по id и по части её названия.

Поиск по id

Добавим новый метод в интерфейс CountryService:

interface CountryService {
    // ...
    fun getById(id: Int): CountryDto
}

Реализация этого метода в CountryServiceImpl будет выглядеть так:

override fun getById(id: Int): CountryDto =
    countryRepository.findByIdOrNull(id)
        ?.toDto()
        ?: throw RuntimeException("Country not found")

Мы используем стандартный метод findByIdOrNull(), который доступен в нашем репозитории благодаря наследованию от CrudRepository. Этот метод возвращает сущность из БД или null, если записи с таким id не существует. Мы преобразуем полученную сущность с помощью ранее определённого метода расширения CountryEntity.toDto(). Если же мы получим null, то благодаря элвис-оператору кидаем исключение RuntimeException с сообщением о том, что запись не найдена.

В следующих статьях мы научимся делать кастомные исключения, которые могут содержать дополнительную информацию об ошибке.

Теперь добавим новый GET-метод в контроллер:

@GetMapping("/{id}")
fun getById(@PathVariable("id") id: Int): CountryDto =
    countryService.getById(id)

В аннотации @GetMapping мы указываем шаблон урла, который связан с данным методом. То есть id записи будет передаваться в самом урле. И аннотация @PathVariable связывает его с параметром метода.

Теперь запустим проект и попробуем подгрузить страну по её id. Делаем следующий запрос:

curl http://127.0.0.1:8080/countries/5

В ответ получим страну с id = 5:

{
    "id": 5,
    "name": "Франция",
    "population": 68959599
}

Поиск по имени

Искать страну по id не очень удобно. Было бы проще искать страны по части названия.

Нам нужно добавить новый метод в репозиторий, опять-таки следуя соглашениям об именовании:

interface CountryRepository : CrudRepository<CountryEntity, Int> {
    // ...
    fun findByNameStartsWithIgnoreCaseOrderByName(prefix: String): List<CountryEntity>
}

Метод findByNameStartsWithIgnoreCaseOrderByName() ищет страны, у которых название начинается с указанного префикса (первые несколько букв). При этом поиск выполняется регистронезависимый. Все страны, удовлетворяющие условию, сортируются по имени. Более подробно про соглашения об именовании можно почитать в статье Написание запросов в Spring Data JPA. Как и в случае списка всех стран, Spring Data сам сгенерит реализацию данного метода.

Перейдём в сервисный слой и добавим новый метод в CountryService:

interface CountryService {
    // ...
    fun search(prefix: String): List<CountryDto>
}

Метод search() будет принимать на вход префикс названия страны и возвращать все страны, которые с него начинаются. Реализация этого метода в CountryServiceImpl:

override fun search(prefix: String): List<CountryDto> =
    countryRepository.findByNameStartsWithIgnoreCaseOrderByName(prefix)
        .map { it.toDto() }

Полученный список сущностей БД мы преобразуем в список dto с помощью метода расширения toDto().

Наконец, добавляем метод поиска searchCountries() в контроллер:

@GetMapping("/search")
fun searchCountries(@RequestParam("prefix") prefix: String): List<CountryDto> =
    countryService.search(prefix)

Благодаря аннотации @RequestParam, префикс он принимает как параметр запроса.

Теперь запускаем проект и делаем следующий запрос:

curl http://127.0.0.1:8080/countries/search?prefix=%D0%A4%D0%A0 # prefix=ФР

Здесь мы для русских букв «ФР» выполняем url-кодирование. Кстати, на моём сайте есть специальная утилита для этого.

В ответ получим список с единственной страной, которая начинается с этого префикса.

[
    {
        "id": 5,
        "name": "Франция",
        "population": 68959599
    }
]

И как видите, регистр букв здесь не важен.

В следующей статье Spring Data JPA, REST и Kotlin: создание, обновление, удаление мы научимся модифицировать записи в базе данных.



Комментарии

Добавить комментарий

×

devmark.ru