Продолжим упрощать предыдущий пример работы с базой. Как мы видели, 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 и нашёл работу. Я вам очень благодарен !.
У вас суперский сайт — наполнение отличное, темы проработаны хорошо! Надеюсь, вы его не забросите!