1. введение
Spring Data JPA позволяет нам определять производные методы, которые считывают, обновляют или удаляют записи из базы данных. Это очень полезно, так как уменьшает шаблонный код на уровне доступа к данным.
В этом уроке мы сосредоточимся на определении и использовании методов удаления, полученных из данных Spring с практическими примерами кода.
2. Производное удаление Методами
Во-первых, давайте приведем наш пример. Мы определим объект Fruit , чтобы сохранить название и цвет товаров, доступных в магазине фруктов:
@Entity public class Fruit { @Id private long id; private String name; private String color; // standard getters and setters }
Затем мы добавим наш репозиторий для работы с сущностями Fruit , расширив интерфейс JpaRepository и добавив наши производные методы в этот класс.
Производные методы могут быть определены как ГЛАГОЛ + атрибут, определенный в сущности. Некоторые из разрешенных глаголов: find By, deletedby, и remove By .
Давайте выведем метод для удаления Фруктов s по их имени :
@Repository public interface FruitRepository extends JpaRepository{ Long deleteByName(String name); }
В этом примере метод deleteByName возвращает количество удаленных записей.
Аналогично, мы также можем получить метод delete формы:
ListdeleteByColor(String color);
Здесь метод delete By Color удаляет все фрукты с заданным цветом и возвращает список удаленных записей.
Давайте проверим производные методы удаления. Во-первых, мы вставим несколько записей в таблицу Fruit , определив данные в test-fruit-data.sql:
insert into fruit(id,name,color) values (1,'apple','red'); insert into fruit(id,name,color) values (2,'custard apple','green'); insert into fruit(id,name,color) values (3,'mango','yellow'); insert into fruit(id,name,color) values (4,'guava','green');
Затем мы удалим все “зеленые” фрукты:
@Transactional @Test @Sql(scripts = { "/test-fruit-data.sql" }) public void givenFruits_WhenDeletedByColor_ThenDeletedFruitsShouldReturn() { Listfruits = fruitRepository.deleteByColor("green"); assertEquals("number of fruits are not matching", 2, fruits.size()); fruits.forEach(fruit -> assertEquals("It's not a green fruit", "green", fruit.getColor())); }
Кроме того, обратите внимание, что нам нужно использовать @Транзакционный аннотация для методов удаления.
Далее, давайте добавим аналогичный тестовый случай для второго delete методом :
@Transactional @Test @Sql(scripts = { "/test-fruit-data.sql" }) public void givenFruits_WhenDeletedByName_ThenDeletedFruitCountShouldReturn() { Long deletedFruitCount = fruitRepository.deleteByName("apple"); assertEquals("deleted fruit count is not matching", 1, deletedFruitCount.intValue()); }
3. Производное удаление Методами
Мы также можем использовать удалено глагол для получения методов удаления:
Long removeByName(String name); ListremoveByColor(String color);
Обратите внимание, что нет никакой разницы в поведении двух типов методов.
Окончательный интерфейс будет выглядеть следующим образом:
@Repository public interface FruitRepository extends JpaRepository{ Long deleteByName(String name); List deleteByColor(String color); Long removeByName(String name); List removeByColor(String color); }
Давайте добавим аналогичные модульные тесты для методов remove By :
@Transactional @Test @Sql(scripts = { "/test-fruit-data.sql" }) public void givenFruits_WhenRemovedByColor_ThenDeletedFruitsShouldReturn() { Listfruits = fruitRepository.removeByColor("green"); assertEquals("number of fruits are not matching", 2, fruits.size()); }
@Transactional @Test @Sql(scripts = { "/test-fruit-data.sql" }) public void givenFruits_WhenRemovedByName_ThenDeletedFruitCountShouldReturn() { Long deletedFruitCount = fruitRepository.removeByName("apple"); assertEquals("deleted fruit count is not matching", 1, deletedFruitCount.intValue()); }
4. Производные удаленные методы против @Query
Мы можем столкнуться со сценарием, в котором имя производного метода слишком велико или включает соединение SQL между несвязанными сущностями.
В этом случае мы также можем использовать аннотации @Query и @Modifying для реализации операций удаления.
Давайте посмотрим эквивалентный код для наших производных методов удаления, используя пользовательский запрос:
@Modifying @Query("delete from Fruit f where f.name=:name or f.color=:color") ListdeleteFruits(@Param("name") String name, @Param("color") String color);
Хотя эти два решения кажутся похожими, и они действительно достигают одного и того же результата, они используют несколько иной подход. Метод @Query создает один запрос JPQL к базе данных. Для сравнения, методы delete By выполняют запрос на чтение, а затем удаляют каждый из элементов по одному.
Кроме того, метод deletekey может возвращать список удаленных записей, в то время как пользовательский запрос возвращает количество удаленных записей.
5. Заключение
В этой статье мы сосредоточились на методах удаления производных данных Spring. Полный исходный код, используемый в этой статье, можно найти на GitHub .