(1)、JPA介紹:
JPA全稱為Java Persistence API ,Java持久化API是Sun公司在Java EE 5規范中提出的Java持久化接口。JPA吸取了目前Java持久化技術的優點,旨在規范、簡化Java對象的持久化工作。使用JPA持久化對象,並不是依賴於某一個ORM框架。
為什么要使用JAP?
在說為什么要使用JPA之前,我們有必要了解為什么要使用ORM技術。
ORM 是Object-Relation-Mapping,即對象關系影射技術,是對象持久化的核心。ORM是對JDBC的封裝,從而解決了JDBC的各種存在問題:
a) 繁瑣的代碼問題
用JDBC的API編程訪問數據庫,代碼量較大,特別是訪問字段較多的表的時候,代碼顯得繁瑣、累贅,容易出錯。例如:PreparedStatement pstmt=con.prepareStatment("insert into account value(?,?,?,?,?,?,?,?,?)");
ORM則建立了Java對象與數據庫對象之間的影射關系,程序員不需要編寫復雜的SQL語句,直接操作Java對象即可,從而大大降低了代碼量,也使程序員更加專注於業務邏輯的實現。
b) 數據庫對象連接問題
關系數據對象之間,存在各種關系,包括1對1、1對多、多對1、多對多、級聯等。在數據庫對象更新的時候,采用JDBC編程,必須十分小心處理這些關系,以保證維持這些關系不會出現錯誤,而這個過程是一個很費時費力的過程。
ORM建立Java對象與數據庫對象關系影射的同時,也自動根據數據庫對象之間的關系創建Java對象的關系,並且提供了維持這些關系完整、有效的機制。
c) 系統架構問題
JDBC屬於數據訪問層,但是使用JDBC編程時,必須知道后台是用什么數據庫、有哪些表、各個表有有哪些字段、各個字段的類型是什么、表與表之間什么關系、創建了什么索引等等與后台數據庫相關的詳細信息。
使用ORM技術,可以將數據庫層完全隱蔽,呈獻給程序員的只有Java的對象,程序員只需要根據業務邏輯的需要調用Java對象的Getter和 Setter方法,即可實現對后台數據庫的操作,程序員不必知道后台采用什么數據庫、有哪些表、有什么字段、表與表之間有什么關系。
d) 性能問題
采用JDBC編程,在很多時候存在效率低下的問題。
pstmt =conn.prepareStatement("insert into user_info values(?,?)");
for (int i=0; i<1000; i++) {
pstmt.setInt(1,i);
pstmt.setString(2,"User"+i.toString());
pstmt.executeUpdate();
}
以上程序將向后台數據庫發送1000次SQL語句執行請求,運行效率較低。
采用ORM技術,ORM框架將根據具體數據庫操作需要,會自動延遲向后台數據庫發送SQL請求,ORM也可以根據實際情況,將數據庫訪問操作合成,盡量減少不必要的數據庫操作請求
知道Jpa是一種規范,而Hibernate是它的一種實現。除了Hibernate,還有EclipseLink(曾經的toplink),OpenJPA等可供選擇,所以使用Jpa的一個好處是,可以更換實現而不必改動太多代碼。
在play中定義Model時,使用的是jpa的annotations,比如javax.persistence.Entity, Table, Column, OneToMany等等。但它們提供的功能基礎,有時候想定義的更細一些,難免會用到Hibernate本身的annotation。我當時想,jpa這 么弱還要用它干什么,為什么不直接使用hibernate的?反正我又不會換成別的實現。
因為我很快決定不再使用hibernate,這個問題就一直放下了。直到我現在在新公司,做項目要用到Hibernate。
我想拋開jpa,直接使用hibernate的注解來定義Model,很快發現了幾個問題:
- jpa中有Entity, Table,hibernate中也有,但是內容不同
- jpa中有Column,OneToMany等,Hibernate中沒有,也沒有替代品
我原以為hibernate對jpa的支持,是另提供了一套專用於jpa的注解,但現在看起來似乎不是。一些重要的注解如Column, OneToMany等,hibernate沒有提供,這說明jpa的注解已經是hibernate的核心,hibernate只提供了一些補充,而不是兩 套注解。要是這樣,hibernate對jpa的支持還真夠足量,我們要使用hibernate注解就必定要使用jpa。
實際情況是不是這樣?在被群里(Scala交流群132569382)的朋友鄙視一番卻沒有給出滿意答案的時候,我又想起了萬能的stackoverflow,上去提了兩個問:
- http://stackoverflow.com/questions/8306742/if-i-want-to-use-hibernate-with-annotation-do-i-have-to-use-javax-persistence
- http://stackoverflow.com/questions/8306793/why-jpa-and-hibernate-both-have-entity-and-table-annotations
第一個是問如果想用hibernate注解,是不是一定會用到jpa的。網友的回答:“是。如果hibernate認為jpa的注解夠用,就直接用。否則會弄一個自己的出來作為補充”
第二個是問,jpa和hibernate都提供了Entity,我們應該用哪個,還是說可以兩個一起用?網友回答說“Hibernate的Entity是繼承了jpa的,所以如果覺得jpa的不夠用,直接使用hibernate的即可”