JavaRush/Java курси/Модуль 4. Робота з БД/Управління оновленням даних

Управління оновленням даних

Відкрита

1. Час зміни даних

Коли ти зберігаєш різні записи у базі даних протягом довгих років, дуже часто виникають два питання:

  • Коли цей запис було додано до бази даних?
  • Коли цей запис змінювався востаннє?

Це настільки часті завдання, що практично до кожної таблиці в базі даних додають дві колонки:

  • created_time
  • updated_time

У першій зберігається дата та час створення запису, а в другій — дата та час її останньої зміни. І в кожному Entity-класі є поля:

@Entity
@Table(name = "entities")
public class Entity {
  ...

  @Column(name="created_time")
  private Date created;

  @Column(name="updated_time")
  private Date updated;
}

Hibernate може взяти на себе всю роботу з контролю за часом оновлення об'єктів у базі за допомогою двох анотацій — @CreationTimestamp та @UpdateTimestamp.

Приклад:

@Entity
@Table(name = "entities")
public class Entity {
  ...

@CreationTimestamp
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "create_date")
    private Date createDate;

@UpdateTimestamp
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "modify_date")
private Date modifyDate;
}

У колонках, які позначено цими анотаціями, завжди зберігатиметься правильний час створення об'єкта та його останньої зміни.

2. Анотація @PrePersist

Якщо тобі потрібні якісь складніші сценарії для контролю часу об'єкта, то Hibernate має анотації і на цей випадок. Ними можна позначити методи класу, і Hibernate викличе ці методи, коли зберігатиме об'єкт до бази. Загалом таких анотацій 7:

@PrePersist Викликається перед збереженням об'єкта в базу. (SQL INSERT)
@PostPersist Викликається одразу після збереження об'єкта в базу. (SQL INSERT)
@PreRemove Викликається перед видаленням об'єкта з бази.
@PostRemove Викликається після видалення об'єкта з бази.
@PreUpdate Викликається перед оновленням (SQL UPDATE) об'єкта в базі.
@PostUpdate Викликається після оновлення (SQL UPDATE) об'єкта в базі.
@PostLoad Викликається після того, як об'єкт було завантажено з бази.

Давай напишемо приклад, де ми прописуємо класу правильний час створення та оновлення його об'єктів:

@Entity
@Table(name = "entities")
public class Entity {
  ...

  @Column(name="created_time")
  private Date created;

  @Column(name="updated_time")
  private Date updated;

  @PrePersist
  protected void onCreate() {
    created = New Date();
  }

  @PreUpdate
  protected void onUpdate() {
  updated = New Date();
  }
}

Якщо Hibernate зберігає об'єкт вперше, він викличе метод, позначений анотацією @PrePersist. Якщо оновлює існуючий об'єкт у базі, то викличе метод, позначений анотацією @PreUpdate.

3. Додаємо свої EntityListeners

Якщо тобі дуже треба, ти можеш відокремити методи, які викликає Hibernate, від об'єкта, у якого він їх викликає. Специфікація JPA дозволяє тобі оголосити listener-класи, які будуть викликатись у певні моменти обробки Entity-об'єктів.

Якщо у тебе багато схожих Entity-об'єктів, ти можеш винести їхню частину до базового класу і додати Listener, який би керував їхньою поведінкою. Приклад:

@MappedSuperclass
public abstract class BaseEntity {

    private Timestamp createdOn;

    private Timestamp updatedOn;

}


@Entity
public class User extends BaseEntity {

     @Id
     private Long id;

     private String name;
}

Тоді для класу BaseEntity можна створити спеціальний listener-клас:

public class TimeEntityListener {

    public void onPersist(Object entity) {
    if (entity instanceof BaseEntity) {
        BaseEntity baseEntity = (BaseEntity) entity;
        baseEntity.createdOn = now();
    }
    }

    public void onUpdate(Object entity) {
    if (entity instanceof BaseEntity) {
        BaseEntity baseEntity = (BaseEntity) entity;
        baseEntity.updatedOn = now();
    }
    }

    private Timestamp now() {
    return Timestamp.from(LocalDateTime.now().toInstant(ZoneOffset.UTC) );
    }
}

І зв'язати клас User та його listener можна за допомогою парочки анотацій:

@Entity
@EntityListeners(class=TimeEntityListener.class)
public class User extends BaseEntity {

     @Id
     private Long id;

     private String name;
}

1
Задача
Модуль 4. Робота з БД,  12 рівень4 лекція
Недоступна
Час створення та зміни даних
task1204
Коментарі
  • популярні
  • нові
  • старі
Щоб залишити коментар, потрібно ввійти в систему
Для цієї сторінки немає коментарів.