«1. Обзор

В этом руководстве мы рассмотрим использование аннотации @EmbeddedId и метода «findBy» для запроса объекта JPA на основе составного ключа.

Следовательно, мы будем использовать аннотации @EmbeddeId и @Embeddable для представления составных ключей в объектах JPA. Нам также нужно использовать Spring JpaRepository для достижения нашей цели.

Мы сосредоточимся на запросе объектов по частичному первичному ключу.

2. Необходимость в @Embeddable и @EmbeddedId

В программном обеспечении мы сталкиваемся со многими случаями использования, когда нам нужен составной первичный ключ для определения записи в таблице. Составные первичные ключи — это ключи, которые используют более одного столбца для уникальной идентификации строки в таблице.

Мы представляем составной первичный ключ в Spring Data, используя аннотацию @Embeddable для класса. Затем этот ключ встраивается в соответствующий класс сущностей таблицы в качестве составного первичного ключа с помощью аннотации @EmbeddedId в поле типа @Embeddable.

3. Пример

Рассмотрим таблицу book, в которой запись book имеет составной первичный ключ, состоящий из автора и имени. Иногда нам может понадобиться найти книги по части первичного ключа. Например, пользователь может захотеть найти книги только определенного автора. Мы узнаем, как это сделать с помощью JPA.

Наше основное приложение будет состоять из @Embeddable BookId и @Entity Book с @EmbeddedId BookId.

3.1. @Embeddable

Давайте определим наш класс BookId в этом разделе. Автор и имя будут указывать уникальный BookId — класс Serializable и реализует методы equals и hashCode:

@Embeddable
public class BookId implements Serializable {

    private String author;
    private String name;

    // standard getters and setters
}

3.2. @Entity и @EmbeddedId

Наша сущность Book имеет @EmbeddedId BookId и другие поля, связанные с книгой. BookId сообщает JPA, что объект Book имеет составной ключ:

@Entity
public class Book {

    @EmbeddedId
    private BookId id;
    private String genre;
    private Integer price;

    //standard getters and setters
}

3.3. Репозиторий JPA и именование методов

Давайте быстро определим интерфейс нашего репозитория JPA, расширив JpaRepository сущностью Book, а также BookId:

@Repository
public interface BookRepository extends JpaRepository<Book, BookId> {

    List<Book> findByIdName(String name);

    List<Book> findByIdAuthor(String author);
}

Мы используем часть имен полей переменной id для получения нашего запроса Spring Data методы. Следовательно, JPA интерпретирует частичный запрос первичного ключа как:

findByIdName -> directive "findBy" field "id.name"
findByIdAuthor -> directive "findBy" field "id.author"

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

JPA можно использовать для эффективного сопоставления составных ключей и запроса их с помощью производных запросов.

В этой статье мы видели небольшой пример запуска частичного поиска по полю id. Мы рассмотрели аннотацию @Embeddable для представления составного первичного ключа и аннотацию @EmbeddedId для вставки составного ключа в сущность.

Наконец, мы увидели, как использовать производные методы JpaRepository findBy для поиска с частичными полями идентификатора.

Как всегда, пример кода для этого руководства доступен на GitHub.