Перейти к основному содержимому

Определение объектов JPA

· 5 мин. чтения

1. Введение

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

2. Сущность

Сущности в JPA — это не что иное, как POJO, представляющие данные, которые могут быть сохранены в базе данных. Сущность представляет собой таблицу, хранящуюся в базе данных. Каждый экземпляр объекта представляет собой строку в таблице.

2.1. Аннотация объекта _

Допустим, у нас есть POJO под названием Student, который представляет данные студента, и мы хотели бы сохранить его в базе данных:

public class Student {

// fields, getters and setters

}

Чтобы сделать это, мы должны определить сущность, чтобы JPA знал о ней.

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

@Entity
public class Student {

// fields, getters and setters

}

Имя объекта по умолчанию совпадает с именем класса. Мы можем изменить его имя, используя элемент name :

@Entity(name="student")
public class Student {

// fields, getters and setters

}

Поскольку различные реализации JPA будут пытаться создать подкласс нашей сущности, чтобы обеспечить свою функциональность, классы сущностей не должны объявляться final .

2.2. Аннотация идентификатора _

Каждый объект JPA должен иметь первичный ключ, который однозначно идентифицирует его. Аннотация @Id определяет первичный `` ключ. Мы можем генерировать идентификаторы разными способами, которые указаны в аннотации @GeneratedValue .

Мы можем выбрать одну из четырех стратегий генерации идентификатора с элементом стратегии . Значение может быть AUTO, TABLE, SEQUENCE или IDENTITY:

@Entity
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

private String name;

// getters and setters
}

Если мы укажем GenerationType . AUTO , провайдер JPA будет использовать любую стратегию для генерации идентификаторов.

Если мы аннотируем поля сущности, провайдер JPA будет использовать эти поля для получения и установки состояния сущности. В дополнение к доступу к полю мы также можем использовать доступ к свойствам или смешанный доступ, что позволяет нам использовать доступ к полям и свойствам в одном и том же объекте .

2.3. Аннотация к таблице

В большинстве случаев имя таблицы в базе данных и имя объекта не будут совпадать.

В этих случаях мы можем указать имя таблицы с помощью аннотации @Table :

@Entity
@Table(name="STUDENT")
public class Student {

// fields, getters and setters

}

Мы также можем упомянуть схему, используя элемент schema :

@Entity
@Table(name="STUDENT", schema="SCHOOL")
public class Student {

// fields, getters and setters

}

Имя схемы помогает отличить один набор таблиц от другого.

Если мы не используем аннотацию @Table , имя таблицы будет именем сущности.

2.4. Аннотация столбца _

Как и в случае с аннотацией @Table , мы можем использовать аннотацию @Column для указания сведений о столбце в таблице.

Аннотация @Column имеет множество элементов, таких как имя, длина, обнуляемый и уникальный :

@Entity
@Table(name="STUDENT")
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

@Column(name="STUDENT_NAME", length=50, nullable=false, unique=false)
private String name;

// other fields, getters and setters
}

Элемент name указывает имя столбца в таблице. Элемент length определяет его длину. Элемент nullable указывает, допускает ли столбец значение null или нет, а элемент unique указывает, является ли столбец уникальным.

Если мы не укажем эту аннотацию, имя столбца в таблице будет именем поля.

2.5. Переходная аннотация _

Иногда мы можем захотеть сделать поле непостоянным. Для этого мы можем использовать аннотацию @Transient . Он указывает, что поле не будет сохраняться.

Например, мы можем рассчитать возраст студента по дате рождения.

Итак, давайте аннотируем поле age аннотацией @Transient :

@Entity
@Table(name="STUDENT")
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

@Column(name="STUDENT_NAME", length=50, nullable=false)
private String name;

@Transient
private Integer age;

// other fields, getters and setters
}

В результате возраст поля не будет сохранен в таблице.

2.6. Временная аннотация _

В некоторых случаях нам может потребоваться сохранить временные значения в нашей таблице.

Для этого у нас есть аннотация @Temporal :

@Entity
@Table(name="STUDENT")
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

@Column(name="STUDENT_NAME", length=50, nullable=false, unique=false)
private String name;

@Transient
private Integer age;

@Temporal(TemporalType.DATE)
private Date birthDate;

// other fields, getters and setters
}

Однако в JPA 2.2 у нас также есть поддержка java.time.LocalDate, java.time.LocalTime, java.time.LocalDateTime, java.time.OffsetTime и java.time.OffsetDateTime.

2.7. Пронумерованная аннотация _

Иногда нам может понадобиться сохранить тип перечисления Java.

Мы можем использовать аннотацию @Enumerated , чтобы указать, должно ли перечисление сохраняться по имени или по порядковому номеру (по умолчанию):

public enum Gender {
MALE,
FEMALE
}
@Entity
@Table(name="STUDENT")
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

@Column(name="STUDENT_NAME", length=50, nullable=false, unique=false)
private String name;

@Transient
private Integer age;

@Temporal(TemporalType.DATE)
private Date birthDate;

@Enumerated(EnumType.STRING)
private Gender gender;

// other fields, getters and setters
}

На самом деле, нам вообще не нужно указывать аннотацию @Enumerated , если мы собираемся сохранить пол по порядковому номеру перечисления .

Однако, чтобы сохранить пол по имени перечисления , мы настроили аннотацию с помощью EnumType.STRING.

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

В этой статье мы узнали, что такое объекты JPA и как их создавать. Мы также узнали о различных аннотациях, которые мы можем использовать для дальнейшей настройки объекта.

Полный код для этой статьи можно найти на Github .