1. 程式人生 > >Hibernate設定時間戳的預設值和更新時間的自動更新

Hibernate設定時間戳的預設值和更新時間的自動更新

Generated and default property values

生成的和預設的屬性值

The database sometimes generates a property value, usually when you insert a row for the first time. 

資料庫通常會在第一次插入一條資料的時候產生一個屬性值。

Examples of database-generated values are a creation timestamp, a default price for an item, and a trigger that runs for every modification.

資料庫產生值得一個例子就是建立時的時間戳,物品的初始預設價格,以及每次修改時執行的觸發器。

Typically, Hibernate applications need to refresh instances that contain any properties for which the database generates values, after saving. 

典型的,HIbernate應用程式在儲存之後需要重新整理包含由資料庫為其生成值的任何屬性物件。

This means you would have to make another round trip to the database to read the value after inserting or updating a row.

這就意味著,你不得不進行另一次的資料庫訪問來讀取插入或者更新一行資料之後的值。

Marking properties as generated, however, lets the application delegate this responsibility to Hibernate. 

然而,把屬性標識為已生成,就讓應用程式把責任委託給了hibernate。

Essentially, whenever Hibernate issues an SQL INSERT or UPDATE for an entity that has declared generated properties, it does a SELECT immediately afterward to retrieve the generated values.

基本上,當hibernate為一個聲明瞭已生成標識的屬性的實體執行SQL插入或者更新的時候,它會立刻執行一個select來獲取新生成的值。

You mark generated properties with the @org.hibernate.annotations.Generated annotation.

你使用註解@org.hibernate.annotations.Generated來標識一個已生成屬性。

Listing 5.4 Database-generated property values

程式碼清單5.4 資料庫生成的屬性值展示

@Temporal(TemporalType.TIMESTAMP)
@Column(insertable = false, updatable = false)
@org.hibernate.annotations.Generated(
org.hibernate.annotations.GenerationTime.ALWAYS
)
protected Date lastModified;
@Column(insertable = false)
@org.hibernate.annotations.ColumnDefault("1.00")
@org.hibernate.annotations.Generated(
org.hibernate.annotations.GenerationTime.INSERT
)
protected BigDecimal initialPrice;
Available settings for GenerationTime are ALWAYS and INSERT.
GenerationTime的可用的設定選項是ALWAYS和INSERT。

With ALWAYS, Hibernate refreshes the entity instance after every SQL UPDATE or INSERT.

當使用ALWAYS的時候,Hibernate每次執行SQL UPADATE或者INSERT插入的時候就會重新整理實體。

The example assumes that a database trigger will keep the lastModified property current. 

例子假定資料庫的觸發器能保持讓lastModified屬性保持是當前時間。

The property should also be marked read-only, with the updatable and insertable parameters of @Column. 

屬性也應該標識為只讀,只讀屬性使用註解@Column的updatable和insertable來實現。

If both are set to false, the property’s column(s) never appear in the INSERT or UPDATE statements, and you let the database generate the value.

如果兩個都設定了false,屬性列表就用於不會在INSERT或者UPADATE語句中出現了,這些列的數值就由資料庫來產生值咯。

With GenerationTime.INSERT, refreshing only occurs after an SQL INSERT, to retrieve the default value provided by the database.

使用GenerationTime.INSERT,只會在SQL INSERT的時候出現,來獲取資料庫的預設值。

 Hibernate also maps the property as not insertable. hibernate也會對映為屬性不可插入。

The @ColumnDefault Hibernate annotation sets the default value of the column when Hibernate exports and generates the SQL schema DDL.

@ColumnDefault屬性註解,設定列表的預設屬性,當hibernate匯出和生成SQL schenma DDL的時候。

Timestamps are frequently automatically generated values, either by the database,as in the previous example, or by the application. Let’s have a closer look at the @Temporal annotation you saw in listing 5.4.

Timestamps是自動生成值中經常使用的,或者是通過資料庫產生,如之前的例子,或者是通過應用程式生成,可以通過仔細觀看下面程式碼清單5.4中的註解。

The lastModified property of the last example was of type java.util.Date, and a database trigger on SQL INSERT generated its value. 

在、上個例子的java.utia.Date型別中的 lastModifiied屬性和資料庫的SQL INSERT觸發器產生值。

The JPA specification requires that you annotate temporal properties with @Temporal to declare the accuracy of the
SQL data type of the mapped column. 

JPA規範要求使用@Temporal註解來宣告對映的SQL資料型別。

The Java temporal types are java.util.Date,java.util.Calendar, java.sql.Date, java.sql.Time, and java.sql.Timestamp.

java型別有如下java.util.Date,java.util.Calendar, java.sql.Date, java.sql.Time, and java.sql.Timestamp。

Hibernate also supports the classes of the java.time package available in JDK 8. (Actually, the annotation isn’t required if a converter is applied or applicable for the property.You’ll see converters again later in this chapter.)

hibernate也提供JDK8中的java.time包。(實際上如果使用了converter轉換器之後,註解是不需要了。在下一節會看在次看到轉換器)

The next listing shows a JPA-compliant example: a typical “this item was created on” timestamp property that is saved once but never updated.

下一個程式碼清單展示一個JPA的相容性例子。一個典型的 被創建於欄位 一次儲存的時候建立不被更新。

@Temporal(TemporalType.TIMESTAMP)
@Column(updatable = false)
@org.hibernate.annotations.CreationTimestamp
protected Date createdOn;
// Java 8 API
// protected Instant reviewedOn;

OK書本內容就是這樣寫的,下面看我們自己的需求和實現。

我們在定義JPA的entity時,有需要設定資料庫時間戳的需求,一般情況下,會有一個欄位需求記錄建立時間,一個欄位記錄更新時間。那麼在hibernate配置中是如何操作的呢?

看如下:

@Entity
@Table(name="RS_SIGNUPUSER")
public class RsSignUpUser {
  @Id
  @GenericGenerator(name="UUIDGENERATE",strategy="uuid2")
  @GeneratedValue(generator="UUIDGENERATE")
  @Column(name="ID",length=36)
  private String ID;
   @Temporal(TemporalType.TIMESTAMP)
  @Column(updatable = false)
  @org.hibernate.annotations.CreationTimestamp 
  private Date CREATETIME; 
  @Column(name="UPDATETIME")
  @org.hibernate.annotations.UpdateTimestamp
  @Temporal(TemporalType.TIMESTAMP)
  private Date UPDATETIME; 
 
略去了getters和setters方法。

建立的時候

		EntityManager entityManager = entityManagerFactory.createEntityManager();
		entityManager.getTransaction().begin();
		entityManager.persist( new Event( "Our very first event!", new Date() ) );
		RsSignUpUser rsuu = new RsSignUpUser();
		rsuu.setUSERZYBM("1");
		rsuu.setZONECODE("1");
		entityManager.persist(rsuu);

睡眠一秒,更新
		entityManager.getTransaction().commit();
		entityManager.close();

		// now lets pull events from the database and list them
		entityManager = entityManagerFactory.createEntityManager();
		entityManager.getTransaction().begin();
  
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
        List<RsSignUpUser> result1 = entityManager.createQuery( "from RsSignUpUser", RsSignUpUser.class ).getResultList();
		for ( RsSignUpUser event : result1 ) {
			event.setBZ("bb");
		}		
        entityManager.getTransaction().commit();
        entityManager.close();

可以看到資料庫的數值:


時間是存在的。當然也可以在資料庫的定義中增加,但是目前發現hibernate自動生成的表結構中,不能生成表註釋和欄位註釋啊,一大遺憾啊。