Рубрики
Без рубрики

Spring Data JPA – Добавление метода во все репозитории

Практическое руководство по добавлению пользовательских методов во все репозитории в Spring Data JPA.

Автор оригинала: baeldung.

1. Обзор

Spring Data значительно упрощает процесс работы с сущностями, просто определяя интерфейсы репозитория. Они поставляются с набором предопределенных методов и позволяют добавлять пользовательские методы в каждый интерфейс.

Однако, если мы хотим добавить пользовательский метод, доступный во всех репозиториях, процесс немного сложнее. Итак, вот что мы рассмотрим здесь с Spring Data JPA.

Для получения дополнительной информации о настройке и использовании Spring Data JPA ознакомьтесь с нашими предыдущими статьями: Руководство по гибернации с Spring 4 и Введение в Spring Data JPA .

2. Определение базового интерфейса репозитория

Во-первых, мы должны создать новый интерфейс, который объявляет наш пользовательский метод:

@NoRepositoryBean
public interface ExtendedRepository 
  extends JpaRepository {
 
    public List findByAttributeContainsText(String attributeName, String text);
}

Наш интерфейс расширяет интерфейс JpaRepository , чтобы мы могли извлечь выгоду из всего стандартного поведения.

Вы также заметите, что мы добавили @NoRepositoryBean аннотация. Это необходимо, потому что в противном случае поведение Spring по умолчанию заключается в создании реализации для всех подинтерфейсов Хранилище.

Здесь мы хотим предоставить нашу реализацию, которую следует использовать, поскольку это всего лишь интерфейс, предназначенный для расширения фактическими интерфейсами DAO для конкретных сущностей.

3. Реализация базового класса

Далее мы представим нашу реализацию интерфейса Extended Repository :

public class ExtendedRepositoryImpl
  extends SimpleJpaRepository implements ExtendedRepository {
    
    private EntityManager entityManager;

    public ExtendedRepositoryImpl(JpaEntityInformation 
      entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityManager = entityManager;
    }

    // ...
}

Этот класс расширяет SimpleJpaRepository класс, который является классом по умолчанию, используемым Spring для предоставления реализаций интерфейсов репозитория.

Для этого необходимо создать конструктор с параметрами JpaEntityInformation и EntityManager , который вызывает конструктор из родительского класса.

Нам также нужно свойство EntityManager для использования в нашем пользовательском методе.

Кроме того, мы должны реализовать пользовательский метод, унаследованный от интерфейса Extended Repository :

@Transactional
public List findByAttributeContainsText(String attributeName, String text) {
    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    CriteriaQuery cQuery = builder.createQuery(getDomainClass());
    Root root = cQuery.from(getDomainClass());
    cQuery
      .select(root)
      .where(builder
        .like(root.get(attributeName), "%" + text + "%"));
    TypedQuery query = entityManager.createQuery(cQuery);
    return query.getResultList();
}

Здесь метод findbyattributes содержит Text() ищет все объекты типа T, которые имеют определенный атрибут, содержащий значение String , заданное в качестве параметра.

4. Конфигурация JPA

Чтобы указать Spring использовать наш пользовательский класс вместо класса по умолчанию для создания реализаций репозитория, мы можем использовать атрибут repositoryBaseClass |/:

@Configuration
@EnableJpaRepositories(basePackages = "org.baeldung.persistence.dao", 
  repositoryBaseClass = ExtendedRepositoryImpl.class)
public class StudentJPAH2Config {
    // additional JPA Configuration
}

5. Создание репозитория сущностей

Далее давайте посмотрим, как мы можем использовать наш новый интерфейс.

Во-первых, давайте добавим простую сущность Student :

@Entity
public class Student {

    @Id
    private long id;
    private String name;
    
    // standard constructor, getters, setters
}

Затем мы можем создать DAO для объекта Student , который расширяет интерфейс Extended Repository :

public interface ExtendedStudentRepository extends ExtendedRepository {
}

И это все! Теперь наша реализация будет иметь пользовательский findByAttribute Contains Text() метод.

Аналогично, любой интерфейс, который мы определяем, расширяя Расширенный репозиторий интерфейс, будет иметь тот же метод.

6. Тестирование репозитория

Давайте создадим тест JUnit , который покажет пользовательский метод в действии:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { StudentJPAH2Config.class })
public class ExtendedStudentRepositoryIntegrationTest {
 
    @Resource
    private ExtendedStudentRepository extendedStudentRepository;
   
    @Before
    public void setup() {
        Student student = new Student(1, "john");
        extendedStudentRepository.save(student);
        Student student2 = new Student(2, "johnson");
        extendedStudentRepository.save(student2);
        Student student3 = new Student(3, "tom");
        extendedStudentRepository.save(student3);
    }
    
    @Test
    public void givenStudents_whenFindByName_thenOk(){
        List students 
          = extendedStudentRepository.findByAttributeContainsText("name", "john");
 
        assertEquals("size incorrect", 2, students.size());        
    }
}

Тест использует репозиторий extended Student/| bean first для создания 3 записей студентов. Затем вызывается метод find By Attribute Contains () , чтобы найти всех студентов, имя которых содержит текст “john”.

Класс Extended Student Repository может использовать как стандартные методы, такие как save () , так и пользовательский метод, который мы добавили.

7. Заключение

В этой краткой статье мы показали, как мы можем добавить пользовательский метод во все репозитории в Spring Data JPA.

Полный исходный код примеров можно найти на GitHub .