16 марта 2023
Тэги: json, Kotlin, PostgreSQL, rest, Spring Boot, Spring Data, SQL, YouTube, руководство.
В предыдущей статье Spring Data JPA, REST и Kotlin: поиск записей мы научились искать записи по id и по части названия страны. Теперь рассмотрим, как реализовать создание записи, её обновление и удаление. Нам потребуется добавить в наше REST API три новых метода.
Методы создания и обновления будут принимать на вход ранее созданную нами DTO (data transfer object), в которой будут указаны все параметры страны. Однако при создании id страны нам неизвестно, поэтому нужно модифицировать DTO так, чтобы оно допускало null в качестве id:
После этого перейдём в сервисный слой и добавим 3 новых метода в интерфейс CountryService:
Метод создания принимает на вход только dto и возвращает id новой записи, т.к. это id устанавливается на стороне базы данных. Метод обновления принимает и dto, и отдельно id страны. Наконец, методу удаления само dto не требуется. Ему нужно указать лишь id страны.
Теперь реализуем метод удаления в CountryServiceImpl:
Аннотация @Transactional указывает на то, что все операции внутри метода будут выполняться в транзакции. Её следует использовать всегда, когда у вас несколько запросов к БД в одном методе. Далее мы преобразуем полученную DTO в сущность с помощью вспомогательного метода расширения CountryDto.toEntity(). После чего передаём объект в метод save(), который появился в нашем репозитории благодаря наследованию от стандартного CrudRepository.
В качестве результата метод save() возвращает экземпляр сущности, в котором уже будет проставлен актуальный id новой записи, назначенный базой.
Вспомогательный метод расширения, преобразующий dto в сущность, выглядит так:
Поскольку id нам неизвестно, но сущность не допускает null, поэтому в id указываем 0. Spring Data JPA таким образом поймёт, что это новая сущность.
Добавим в CountryController новый метод, который будет вызывать сервисный слой:
Аннотация @PostMapping указывает на то, что данный запрос имеет тип POST. @RequestBody говорит о том, что dto будет передаваться в самом теле запроса в формате json.
Теперь мы можем запустить наш сервис и выполнить POST-запрос на создание новой записи:
Данная консольная команда должна быть записана в одну строку. Если вы разбиваете команду на несколько строк, то в конце каждой не забудьте добавить обратный слеш.
На практике для запросов изменения данных часто используют Postman.
В ответ нам приходит id новой записи.
Перейдём к реализации метода обновления update().
Он также выполняется в транзакции. На вход поступает id существующей записи и новые значения полей в dto. Сначала мы подгружаем по id существующую запись с помощью стандартного метода findByIdOrNull(). Если запись не найдена, он вернёт null, и тогда мы кидаем исключение.
Затем в найденной записи меняем значения полей на новые, которые пришли к нам в dto. После чего вызываем тот же метод save(), что и при создании.
Обратите внимание, что мы не меняем id у существующей записи. Тогда Spring Data поймёт, что нужно обновить существующую запись. В ответ метод ничего не возвращает.
Добавим обработчик PUT-метода в CountryController:
@PathVariable связывает параметр метода id с частью урла, на который выполняется запрос. А новые значения полей самой сущности, как и в случае с созданием, передаются в dto.
Как видим, при обновлении в Postman нам ничего не приходит в ответ – значит, запрос выполнен успешно.
Добавим реализацию метода удаления в сервисный слой. Он также выполняется в транзакции.
В нём мы сначала пытаемся найти существующую запись. Как и в случае с обновлением, если запись не найдена, то кидаем исключение. Затем вызываем стандартный метод deleteById(), который появился в нашем репозитории благодаря наследованию от всё того же CrudRepository.
Наконец, добавим обработчик DELETE-метода в контроллер:
Как видите, у него единственный параметр id. Он является частью урла, на который выполняется запрос.
В Postman в случае успешного удаления мы также ничего не возвращаем в ответе.
В следующей статье Spring Data JPA, REST и Kotlin: обработка ошибок мы научимся создавать собственные обработчики ошибок, а также изменим формат ответа при ошибке.
Kotlin, Java, Spring, Spring Boot, Spring Data, SQL, PostgreSQL, Oracle, Linux, Hibernate, Collections, Stream API, многопоточность, файлы, Nginx, Apache, maven, gradle, JUnit, YouTube, новости, руководство, ООП, алгоритмы, головоломки, rest, GraphQL, Excel, XML, json, yaml.