JavaRush /Kurslar /All lectures for AZ purposes /Məlumatların yenilənməsi idarə olunması

Məlumatların yenilənməsi idarə olunması

All lectures for AZ purposes
Səviyyə , Dərs
Mövcuddur

5.1 Məlumatların dəyişmə vaxtı

Məlumatlar bazasında müxtəlif qeydləri uzun illər saxladıqda, çox vaxt iki sual yaranır:

  • Bu qeyd nə vaxt məlumatlar bazasına əlavə olunub?
  • Bu qeyd sonuncu dəfə nə zaman dəyişib?

Bu qədər tez-tez rast gəlinən məsələlərdir ki, demək olar ki, hər bir cədvələ məlumatlar bazasında iki kolon əlavə edirlər:

  • created_time
  • updated_time

Birincidə qeydin yaradılma tarixi və vaxtı saxlanılır, ikincidə isə – onun sonuncu dəyişmə tarixi və vaxtı. Və hər bir Entity sinfində sahələr var:


@Entity
@Table(name = "entities")	
public class Entity {
  ...
 
  @Column(name="created_time")
  private Date created;
 
  @Column(name="updated_time")
  private Date updated;
}

Hibernate obyektlərin məlumatlar bazasındakı yenilənmə zamanı idarə edilməsini iki annotasiya ilə öz üzərinə götürə bilər: @CreationTimestamp@UpdateTimestamp.

Nümunə:


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

Bu annotasiyalarla işarələnmiş kolonlarda obyektin yaradılma və sonuncu dəyişilmə vaxtı həmişə düzgün saxlanacaq.

5.2 Annotasiya @PrePersist

Əgər obyektin vaxtını idarə etmək üçün daha mürəkkəb ssenarilər lazım olsa, Hibernate-də bunun üçün annotasiyalar var. Sinifin metodlarını bu annotasiyalarla işarələyə bilərsən və Hibernate obyekti məlumatlar bazasına saxlayarkən bu metodları çağıracaq. Cəmi 7 belə annotasiya var:

@PrePersist Obyekti məlumatlar bazasına saxlayarkən çağırılır. (SQL INSERT)
@PostPersist Obyekti məlumatlar bazasına saxladıqdan dərhal sonra çağırılır. (SQL INSERT)
@PreRemove Obyekti məlumatlar bazasından silməzdən əvvəl çağırılır.
@PostRemove Obyekti məlumatlar bazasından sildikdən sonra çağırılır.
@PreUpdate Obyekti məlumatlar bazasında yeniləmədən əvvəl çağırılır. (SQL UPDATE)
@PostUpdate Obyekti məlumatlar bazasında yenilədikdən sonra çağırılır. (SQL UPDATE)
@PostLoad Obyekti məlumatlar bazasından yüklədikdən sonra çağırılır.

Gəl, bir nümunə yazaq, burada sinifin obyektlərinin yaradılma və yenilənmə vaxtını doğru qeyd edirik:


@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 obyekti ilk dəfə saxlayanda, @PrePersist annotasiyası ilə işarələnmiş metodu çağıracaq. Məlumatlar bazasında mövcud olan obyekti yeniləyərkən, @PreUpdate annotasiyası ilə işarələnmiş metodu çağıracaq.

5.3 Öz EntityListeners əlavə edirik

Əgər çox ehtiyac varsa, Hibernate-in çağırdığı metodları, onları çağırdığı obyektdən ayıra bilirsən. JPA spesifikasiyası sənə listener-sinifləri elan etməyə imkan verir, bunlar Entity-obyektlərinin müəyyən işləmə anlarında çağırılacaq.

Əgər çox oxşar Entity-obyektlərin varsa, onların bir hissəsini əsas sinifdə toplamaq və onların davranışını idarə edəcək Listener əlavə etmək olar. Nümunə:


@MappedSuperclass
public abstract class BaseEntity {
 
    private Timestamp createdOn;
 
    private Timestamp updatedOn;
 
}


@Entity
public class User extends BaseEntity {
 
     @Id
     private Long id;
 
     private String name;
}

Onda BaseEntity sinfi üçün xüsusi listener-sinif yarada bilərik:


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

Və User sinfi ilə onun listener-in əlaqələndirmək üçün bir neçə annotasiya istifadə edə bilərik:


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

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION