Продолжим упрощать предыдущий пример работы с базой. Как мы видели, JdbcTemplate позволяет писать непосредственно запрос, оставив за кулисами прочие служебные операции.
CrudRepository и PagingAndSortingRepository
Но в Spring Data существует еще готовый репозиторий CrudRepository, который избавляет нас от составления простых запросов. В нем реализованы CRUD-операции для сущности:
- сreate
- read
- update и
- delete
Чтобы им воспользоваться, необходимо написать интерфейс, расширяющий CrudRepository или PagingAndSortingRepository:
public interface AnimalRepository extends PagingAndSortingRepository<Animal, Long> { }
Воспользуемся репозиторием.
Для этого напишем тесты. В жизни тестировать готовый репозиторий не нужно, но поскольку у нас нет интерфейса, методы репозитория можно вызвать в тестах.
CrudRepositoryTest
Метод save() используется для добавления и редактирования сущности.
findById() — для поиска по id.
count() — для подсчета числа элементов в таблице.
Тесты:
@DataJdbcTest public class AnimalRepositoryTest { @Autowired private AnimalRepository dao; @Test void givenId_whenFindThenReturnsAnimal() { Optional<Animal> optionalAnimal = dao.findById(1l); Assertions.assertTrue(!optionalAnimal.isEmpty()); } @Test void givenAnimal_whenSaveThenReturnsAnimal() { Animal newAnimal=new Animal("mouse"); Animal animal = dao.save(newAnimal); Assertions.assertSame(animal, newAnimal); Assertions.assertNotNull(animal.getId()); } @Test void givenId_whenUpdateThenReturnsAnimal() { Optional<Animal> optionalAnimal = dao.findById(1l); optionalAnimal.get().setName("cat1"); Animal updatedAnimal=dao.save(optionalAnimal.get()); Assertions.assertEquals("cat1", updatedAnimal.getName()); } @Test void whenCount_thenCountIsTwo() { long count = dao.count(); Assertions.assertEquals(2 , count); } }
Учтите, что при запуске тестов либо приложения база заполняется двумя животными (файл data.sql):
insert into animal (name) values ('cat'); insert into animal (name) values ('dog');
@id
public class Animal { @Id private long id; private String name; //setters/getters/constructors }
@DataJdbcTest
@DataJdbcTest включает в контекст все бины, унаследованные от CrudRepository. Не унаследованный ни от чего бин @Repository (из предыдущей статьи) не создается, поэтому его приходилось включать в контекст отдельно (и использовать @JdbcTest).
Также @DataJdbcTest откатывает транзакции после каждого теста, приводя базу в первоначальное состояние.
Query Methods
Пока что наш интерфейс AnimalRepository был пустой. Но его можно дополнять и другими методами.
Derived Query Methods
Интересный нам запрос можно создать, просто продекларировав метод с правильным названием, включающим названия нужных полей. Spring Data создает реализацию метода по его названию.
Просто продекларируем в интерфейсе некоторые методы:
Animal findByName(String name); //1 Animal findFirstByName(String name); //2 List<Animal> findByNameNotContaining(String str); (3)
(1) выбрасывает IncorrectResultSizeDataAccessException при неуникальном результате. И null, если Animal с таким именем не найдено.
(2) возвращает первую найденную запись с таким именем. И тоже null, если Animal с таким именем не найдено.
(3) возвращает список Animal, имя которых не содержит str.
Весь список поддерживаемых ключевых слов есть в таблице в документации.
Добавим тесты:
@Test void givenName_whenFindBy_thenReturnsAnimal() { Animal animal = dao.findByName("cat"); Assertions.assertEquals("cat", animal.getName()); } @Test void givenName_whenFindFirstBy_thenReturnsAnimal() { Animal animal = dao.findFirstByName("cat"); Assertions.assertEquals("cat", animal.getName()); }
@Query
В AnimalRepository можно также добавить sql-запрос с помощью @Query:
@Query("select count(*) from animal") int animalCount();
Этот метод приведен для примера, т.к. в CrudRepository уже реализован аналогичный count().
Исходный код
Код примера доступен на GitHub.
Спасибо за сайт! В самом первом тесте похоже надо поправить последнюю строчку.
точно, спасибо, исправлено.
Ребята вам огромное спасибо, с помощью вашего сайта я изучил Spring и нашёл работу. Я вам очень благодарен !.
У вас суперский сайт — наполнение отличное, темы проработаны хорошо! Надеюсь, вы его не забросите!