CodeGym/Java kursus/All lectures for DA purposes/Håndtering af dataopdatering

Håndtering af dataopdatering

Ledig

5.1 Tidspunkt for dataændring

Når du gemmer forskellige poster i en database i mange år, opstår der ofte to spørgsmål:

  • Hvornår blev denne post tilføjet til databasen?
  • Hvornår blev denne post sidst ændret?

Disse er så hyppige opgaver, at der tilføjes to kolonner til næsten hver tabel i databasen:

  • oprettet_tid
  • updated_time

Den første gemmer datoen og klokkeslættet, da posten blev oprettet, og den anden gemmer datoen og klokkeslættet, hvor den sidst blev ændret. Og hver enhedsklasse har felter:

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

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

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

Hibernate kan klare alt arbejdet med at kontrollere, hvornår objekter i databasen opdateres med to anmærkninger @CreationTimestampog @UpdateTimestamp.

Eksempel:

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

Kolonnerne markeret med disse anmærkninger vil altid gemme det korrekte tidspunkt, da objektet blev oprettet, og hvornår det sidst blev ændret.

5.2 @PrePersist annotation

Hvis du har brug for nogle mere komplekse scripts til at kontrollere tidspunktet for et objekt, så har Hibernate også anmærkninger til denne sag. De kan markere klassemetoder, og Hibernate kalder disse metoder, når den gemmer objektet i databasen. Der er 7 sådanne anmærkninger i alt:

@PrePersist Kaldes før objektet gemmes i databasen. (SQL INDSÆT)
@PostPersist Kaldes umiddelbart efter, at objektet er gemt i databasen. (SQL INDSÆT)
@Forudfjern Kaldes før sletning af et objekt i databasen.
@PostRemove Kaldes efter et objekt er blevet slettet fra databasen.
@PreUpdate Kaldes før opdatering (SQL UPDATE) et objekt i databasen.
@PostUpdate Kaldes efter en opdatering (SQL UPDATE) af et objekt i databasen.
@PostLoad Kaldes efter objektet er blevet indlæst fra databasen.

Lad os skrive et eksempel, hvor vi fortæller en klasse det rigtige tidspunkt for at oprette og opdatere dens objekter:

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

Hvis Hibernate gemmer objektet for første gang, kalder det metoden, der er kommenteret med @PrePersist. Hvis den opdaterer et eksisterende objekt i databasen, kalder den metoden, der er markeret med annotationen @PreUpdate.

5.3 Tilføjelse af vores EntityListeners

Hvis du virkelig har brug for det, kan du adskille de metoder, som Hibernate kalder, fra det objekt, som det kalder dem på. JPA-specifikationen giver dig mulighed for at erklære lytterklasser, der vil blive kaldt på bestemte tidspunkter, når du behandler enhedsobjekter.

Hvis du har mange lignende Entity-objekter, kan du flytte nogle af dem ind i basisklassen og tilføje en Listener, der kan kontrollere deres adfærd. Eksempel:

@MappedSuperclass
public abstract class BaseEntity {

    private Timestamp createdOn;

    private Timestamp updatedOn;

}


@Entity
public class User extends BaseEntity {

     @Id
     private Long id;

     private String name;
}

Så for BaseEntity-klassen kan du oprette en speciel lytterklasse:

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

Og du kan forbinde brugerklassen og dens lytter ved hjælp af et par anmærkninger:

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

     @Id
     private Long id;

     private String name;
}

Kommentarer
  • Populær
  • Ny
  • Gammel
Du skal være logget ind for at skrive en kommentar
Denne side har ingen kommentarer endnu