А где же код работы с JPA? | OTUS

А где же код работы с JPA?

Spring_Deep_26.06_2_Site.png

Одной из замечательных возможностей Spring является Spring Data JPA. Это один из «подпроектов» проекта Spring Data. По умолчанию, будем считать, что вы уже знаете, что такое JPA. Итак, нам необходимо написать обычное DAO для некоторой JPA сущности, предположим, Student.

Да, здесь следует сделать небольшую поправку. Когда речь идёт о бизнес-сущностях и JPA, то правильнее применять термин репозиторий (Repository), что мы и будем дальше делать.

На практике интерфейс обычного репозитория выглядел бы как-то так:

public interface StudentRepository {
  Student save(Student entity);
  void delete(Student entity);
  Optional<Student> findById(long id);
  List<Student> findByName(String name);
  // и, возможно, ещё куча методов
}

А сама реализация будет выглядеть примерно таким образом:

@Repository
public class StudentRepositoryImpl implements StudentRepository {

  @PersistenceContext
  private EntityManager em;

  @Override
  public Student save(Student student) {
      em.persist(student);
  }

  @Override
  public void delete(Student entity) {
      em.remove(employee);
  }

  @Override
  public Optional<Student> findById(long id) {
      return em.find(Person.class, id);
  }

  @Override
  public List<Student> findByName(String name) {
    // да, это неправильно, это всего лишь пример
    return em.createQuery("select s from Student where sname="+name)
      .getResultList();
  }

  // и, возможно, ещё куча методов
}

В действительности код в реальном проекте будет выглядеть немного сложнее. Появятся абстрактные Generic-репозитории, и разных специфичных методов поиска entity со сложными JPQL будет достаточно. Да и конфигурация Spring ORM + сама entity Student здесь просто опущены.

А теперь воспользуемся магией Spring Data JPA

Spring Data вводит абстракцию репозитория, поэтому CRUD-методы мы позаимствуем. Итак, наш код будет выглядеть таким образом:

import org.springframework.data.repository.CrudRepository;

public interface StudentRepository extends CrudRepository<Student, Long> {
  List<Student> findByName(String name);
  // и, возможно, ещё куча методов
}

Ну и чтобы этот интерфейс был найден, не забудем поставить:

@EnableJpaRepositories
public class AppConfiguration { /* */ }

И… ВСЁ!

А где же код работы с JPA? Как ни странно, но кода нет! И не будет. Давайте разберёмся, как эта магия работает.

Весь SQL уже написан в entity Student с помощью аннотаций JPA. Действительно, благодаря уже настроенному маппингу этой entity на БД можно написать все методы CRUD, которые определены в интерфейсе CrudRepository.

Но как же метод findByName интерфейса StudentRepository? Несложно догадаться, что Spring Data JPA по имени метода может идентифицировать поле entity, по которому необходимо производить поиск — сгенерировать JPQL, именно тот, который был написан в первой реализации.

В действительности, методы и запросы могут быть сложнее. Приведём пример интерфейса:

public interface StudentRepository extends CrudRepository<Student, Long> {
  List<Student> findByName(String name);
  List<Student> findByNameIgnoreCase(String name);
  List<Student> findByNameOrEmail(String name, String email);
  long deleteByLastname(String lastname);

  // и, возможно, ещё куча методов
}

В документации есть целая «таблица глаголов» для формирования более сложных действий и запросов.

Счастливого использования!

Есть вопрос? Напишите в комментариях!

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться
Популярное
Сегодня тут пусто