下面是另外一個POJO——Person,我們已經對它進行了批註,以便保持;
@Entity
public class Person {
private Long id;
private String name;
private Address address;
public Person() {
}
@Id
@GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToOne
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
上面這段代碼中重要的一部分是用於地址欄位的@ManyToOne批註。@ManyToOne批註是用於描述實體之間關係的一系列批註之一;在本文裡,它表示很多個人可能參考的是一個地址。這就要求參考與一個已經保持了的地址相對應。
Person person=new Person();
person.setName("John Doe");
person.setAddress(address);
…
em.merge(person);
…
Merge方法能夠智能地處理交給它的實體。如果實體是非託管的,就保持它;否則它就會處理存在的差異,並根據需要對資料庫進行更新。這用來處理正在被保持的Person。
這就是保持的基礎概念。當然這要排除我們假設已經存在的EntityManagerFactory。這就是輪子碰到馬路的情形。下面就是建立它的一個典型調用。
EntityManagerFactory emf=Persistence.createEntityManagerFactory("example");
我們要Persistence層根據“example”這個名字建立一個工廠。用來建立這個工廠的配置資訊來自一個叫做persistence.xml的檔案,這個檔案應該在你源碼樹的META-INF目錄下。它定義了一個帶有名字的“persistence-unit”,它有應該如何管理persisitence的細節,底層的哪個persistence提供者將完成這項任務,以及要用到哪個資料庫。下面就是這個程式碼片段:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="example">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>quick.Person</class>
<class>quick.Address</class>
<properties>…</properties>
</persistence-unit>
</persistence>
這裡,我們有一個名為“example”的persistence-unit,我們把這個名字交給createEntityManagerFactory()。我們聯合使用Hibernate的Annotations和EntityManager,因此<provider>元素指向HibernatePersistence提供者。
你可以有一個或者多個<class>元素,每一個都指向一個你想要保持的類。在這個例子裡,你可以看到用於Person和Address的類元素。這裡還有一個<properties>元素,它包含有用於設定實現具體值的<property>元素,這些值會被傳遞用來建立EntityManagerFactory。
在我們的例子裡,我們使用Hibernate和嵌入的HSQLDB。我們需要設定JDBC磁碟機來使用URL,以串連到資料庫並告訴Hibernate要使用什麼樣的SQL語句:
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
<property name="hibernate.connection.url" value="jdbc:hsqldb:data/example"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
嵌入的HSQLDB要用“sa”使用者名稱和空白密碼才能啟動。我們還想要限制hibernate取得相關對象的程度。
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.max_fetch_depth" value="3"/>
最後是hbm2ddl.auto屬性。這用來控制Hibernate在SQL資料庫裡動態地建立所需表格的能力。如果被設定為“建立(create)”,它就會在每次啟動並執行時候清除資料庫並建立新的表格。如果設定為“更新(update)”,它就會嘗試修改原有表格以適合目前的版本的實體;
<property name="hibernate.hbm2ddl.auto" value="create"/>
產生DDL來建立資料庫是大多數實現裡應該都有的東西,但是是否開啟了這一功能就要看各個實現的具體情況了。
有了這個XML檔案,你現在就有了足夠的資訊供createEntityManagerFactory建立簡單的資料庫。你會在本文附帶的原始碼裡發現這個persistence.xml和範例程式碼。要讓它運行起來,你就需要正確的庫。首先,你需要從Hibernate的web網站獲得HSQLDB資料庫、
Hibernate、Hibernate-Annotations以及Hibernate-EntityManager。查看一下讀我檔案,看看你所需要的庫可以從哪裡獲得。一旦讓範例程式碼運行起來了,你就可以開始實驗建立和保持一個簡單的實體。如果想要看給persistence.xml屬性加入SQL之後到底什麼被執行,就要運行下面的代碼;
<property name="hibernate.show_sql" value="true"/>
那麼Hibernate將在執行每個SQL語句的時候進行轉儲。
現在,我們已經知道了保持的基本概念和一些簡單的映射。以後,我們將再看一些可用的批註,以及如何保持集合然後研究一下Glassfish裡面的參考EJB persistence實現。