CodeGym /Java курс /All lectures for BG purposes /Управление на опресняването на данни

Управление на опресняването на данни

All lectures for BG purposes
Ниво , Урок
На разположение

5.1 Време на промяна на данните

Когато съхранявате различни записи в база данни в продължение на много години, често възникват два въпроса:

  • Кога този запис е добавен към базата данни?
  • Кога последно е променен този запис?

Това са толкова чести задачи, че две колони се добавят към почти всяка table в базата данни:

  • създадено_време
  • актуализиран_час

Първият съхранява датата и часа на създаване на записа, а вторият съхранява датата и часа на последната му промяна. И всеки клас 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;
}

Колоните, маркирани с тези анотации, винаги ще съхраняват правилното време, когато обектът е бил създаден и кога е бил последно модифициран.

5.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.

5.3 Добавяне на нашите EntityListeners

Ако наистина трябва, тогава можете да отделите методите, които Hibernate извиква от обекта, на който ги извиква. Спецификацията на JPA ви позволява да декларирате слушателски класове, които ще бъдат извиквани в определени моменти при обработка на обекти 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 можете да създадете специален клас слушател:


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)   );
    }
}

И можете да свържете потребителския клас и неговия слушател, като използвате няколко анотации:


@Entity
@EntityListeners(class= TimeEntityListener.class)
public class User extends BaseEntity {
 
     @Id
     private Long id;
 
     private String name;
}

Коментари
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION