Автор оригинала: Vivek Balasubramaniam.
1. введение
В этом уроке мы узнаем о составных первичных ключах и соответствующих аннотациях в JPA.
2. Составные Первичные Ключи
Составной первичный ключ – также называемый составным ключом – представляет собой комбинацию двух или более столбцов, образующих первичный ключ для таблицы.
В JPA у нас есть два варианта определения составных ключей: Аннотации @IdClass и @EmbeddedId .
Чтобы определить составные первичные ключи, мы должны следовать некоторым правилам:
- Составной класс первичного ключа должен быть открытым
- У него должен быть конструктор no-arg
- Он должен определить equals() и hashCode() методы
- Он должен быть S сериализуемым
3. Аннотация IdClass
Допустим, у нас есть таблица с именем Account и в ней есть два столбца – AccountNumber, AccountType– , которые образуют составной ключ. Теперь мы должны нанести его на карту в JPA.
В соответствии со спецификацией JPA давайте создадим класс Account Id с этими полями первичного ключа:
public class AccountId implements Serializable {
private String accountNumber;
private String accountType;
// default constructor
public AccountId(String accountNumber, String accountType) {
this.accountNumber = accountNumber;
this.accountType = accountType;
}
// equals() and hashCode()
}Далее давайте свяжем Идентификатор учетной записи класс с сущностью Учетная запись .
Для этого нам нужно аннотировать объект с помощью аннотации @IdClass . Мы также должны объявить поля из класса AccountId в сущности Account и аннотировать их с помощью @Id :
@Entity
@IdClass(AccountId.class)
public class Account {
@Id
private String accountNumber;
@Id
private String accountType;
// other fields, getters and setters
}4. Аннотация EmbeddedId
@EmbeddedId является альтернативой аннотации @IdClass .
Давайте рассмотрим другой пример, в котором мы должны сохранить некоторую информацию о Книге с названием и языком в качестве полей первичного ключа.
В этом случае класс первичного ключа BookID должен быть аннотирован с помощью @Embeddable :
@Embeddable
public class BookId implements Serializable {
private String title;
private String language;
// default constructor
public BookId(String title, String language) {
this.title = title;
this.language = language;
}
// getters, equals() and hashCode() methods
}Затем нам нужно встроить этот класс в сущность B ook , используя @EmbeddedId :
@Entity
public class Book {
@EmbeddedId
private BookId bookId;
// constructors, other fields, getters and setters
}5. @IdClass против @EmbeddedId
Как мы только что видели, разница на поверхности между этими двумя заключается в том , что с помощью @IdClass нам пришлось указать столбцы дважды – один раз в AccountId и снова в Account. Но с @EmbeddedId мы этого не сделали.
Однако есть и другие компромиссы.
Например, эти различные структуры влияют на запросы JPQL, которые мы пишем.
Например, с @IdClass запрос немного проще:
SELECT account.accountNumber FROM Account account
С помощью @EmbeddedId мы должны сделать один дополнительный обход:
SELECT book.bookId.title FROM Book book
Кроме того, @IdClass может быть весьма полезен в тех местах, где мы | используем составной ключевой класс, который мы не можем изменить.
Наконец, если мы собираемся получить доступ к частям составного ключа по отдельности, мы можем использовать @IdClass, но в местах, где мы часто используем полный идентификатор в качестве объекта, предпочтительнее использовать @EmbeddedId .
6. Заключение
В этой краткой статье мы рассмотрим составные первичные ключи в JPA.
Как всегда, полный код этой статьи можно найти на Github .