Java開發2.0: 使用Amazon SimpleDB實現雲端儲存,第2部分:使用SimpleJPA實現簡單對象持久化
使用諸如 Grails 的關係架構對幾乎所有類型的應用進行域對象建模是很容易的,但是使用 SimpleDB 又怎麼樣呢?在 Andrew Glover 的介紹 SimpleDB 的系列文章的第 2 部分,他向您介紹了如何使用 SimpleJPA,而非 Amazon SDK,在 SimpleDB 的雲端儲存中實現對象持久化。除了使您能夠使用簡單 Java™ 對象進行域建模(通過 JPA)之外,SimpleJPA 還能夠自動地將基礎資料型別 (Elementary Data Type)轉換成相容 Amazon 的字串。您確實找不到比這更簡單的雲端儲存方法了。
在介紹 SimpleDB 文章的 第一部分 中,我向您介紹了如何使用 Amazon 本身的 API 進行一個 CRUD 網路的賽跑應用的建模。除了對大多數 Java 開發人員而言,Amazon 只使用字串來描述資料類型的方法的明顯獨特性之外,您可能發現自己對於 Amazon API 還有一些疑慮。畢竟,現在使用關聯式資料庫的 API 已經非常標準且成熟了 — 而且更重要的是,他們已經很熟悉這些技術了。
除此之外,現在有許多關係架構實現了 Java Persistence API。因此為各種 RDBMS 進行各種類型的 Java 應用進行域對象建模都是非常容易和常見的。當您已經掌握了一種方法之後,很自然您會對於學習新的域對象建模方法會有一些抵觸 — 而好訊息是使用 SimpleDB 時,您不需要學習新東西。
在 SimpleDB 文章的第 2 部分中,我將向您介紹如何重構第 1 部分的賽跑應用,使之符合 JPA 規範。然後我們將把應用移植到 SimpleJPA,並且探討一些能夠使這個創新的開放源碼平台經過調整而支援 NoSQL 域建模和雲端式的儲存的方法,這一樣很簡單。
為什麼使用 SimpleDB?
Amazon 的 SimpleDB 是一個簡單且極具可擴充性和可靠性的雲端式的資料存放區方法。由於它本質上是非關係/NoSQL,SimpleDB 既靈活又快速。作為 Amazon Web Service 家族的一部分,SimpleDB 使用 HTTP 作為底層通訊機制,所以它能夠支援多種語言,包括 Java 語言、Ruby、C# 和 Perl。SimpleDB 價格也很便宜:根據 SimpleDB 的授權方式,您只需要為您使用的資源支付費用,這跟根據預計使用和空間預先購買授權的傳統方法很不一樣。作為新興的 NoSQL,或非關係資料存放區的一部分,SimpleDB 是與 Google 的 Bigtable 或 CouchDB 相對應的,它們在 這些系列文章中 有相應的介紹。
Hibernate 和 JPA:背景概況
現在有許許多多的 Java 開發人員都使用 Hibernate(和 Spring)實現資料持久化。除了是最先成功的開放源碼項目,Hibernate 也徹底改變了 ORM 領域。在出現 Hibernate 之前,Java 開發人員必須處理複雜的 EJB 實體 Bean;而在這之前,我們只能自己實現 ORM 或者使用來自諸如 IBM® 等供應商的產品。Hibernate 去掉了 EJB 的所有複雜性和開銷,轉而使用我們現在許多人都使用的基於 POJO 的建模平台。
Java Persistence API (JPA) 是由於 Hibernate 創新地使用 POJO 進行資料建模方法的流行而出現的。現在,EJB 3.0 實現了 JPA,Google App Engine 也一樣實現了 JPA。甚至如果您使用 Hibernate EntityManager,那麼 Hibernate 本身也是一個 JPA 實現,
既然 Java 開發人員已經越來越熟悉使用 POJO 對以資料為中心的應用進行建模,那麼可以說,SimpleDB 這樣一個資料存放區應該能夠給我們提供一個類似的選項。畢竟,它與資料庫有些相似,不是嗎?
用對象進行資料建模
要使用 SimpleJPA,我們需要修改一下我們的 Racer 和 Runner 對象,使它們符合 JPA 規範。幸好,JPA 基本要素是很簡單的:給平常的 POJO 加上注釋,而 EntityManager 實現會負責完成其他處理 — 不需要 XML。
JPA 所使用的兩個主要的注釋是 @Entity 和 @Id,這兩個注釋分別將一個 POJO 指定為持久化類,同時確定它的標識鍵。為了將我們的賽跑應用轉換為 JPA,我們也將使用另外兩個管理關聯性的注釋:@OneToMany 和 @ManyToOne。
在本文的第 1 部分中,我已經向您介紹了如何持久化選手和比賽對象了。然而,我沒有使用對象來表示這些實體 — 我只是使用了 Amazon 的原始 API 來儲存這兩個對象的屬性。如果我希望對一個比賽和比賽選手的關係進行建模,那麼我可以編寫如清單 1 所示的代碼:
清單 1. 一個簡單的 Race 對象
public class Race {
private String name;
private String location;
private double distance;
private List<Runner> runners;
//setters and getters left out...
}
在 清單 1 中,我給 Race 對象設定了 4 個屬性,最後一個是一個選手 Collection。接下來,我可以建立一個簡單的 Runner 對象(如清單 2 所示),它包含每位選手的姓名(現在我將盡量保持簡單),與他/她所參加的 Race 執行個體相關的 SSN。
清單 2. 與 Race 相關的一個簡單的 Runner
public class Runner {
private String name;
private String ssn;
private Race race;
//setters and getters left out...
}
您可以從 清單 1 和 2 看到,我在選手和比賽之間邏輯上建立了一個多對一的關係。在實際情況中,可能多對多關係更準確些(選手一般會參加多個比賽),但是這裡這樣做是為了簡單起見。另外,現在我也忽略建構函式、setter 和 getter。我將在後面向您介紹。