1.JPA概述
JPA(Java Persistence API)作為Java EE 5.0平臺(tái)標(biāo)準(zhǔn)的ORM規(guī)范,將得到所有Java EE服務(wù)器的支持。
Sun這次吸取了之前EJB規(guī)范慘痛失敗的經(jīng)歷,在充分吸收現(xiàn)有ORM框架的基礎(chǔ)上,得到了一個(gè)易于使用、伸縮性強(qiáng)的ORM規(guī)范。
從目前的開(kāi)發(fā)社區(qū)的反應(yīng)上看,JPA受到了極大的支持和贊揚(yáng),JPA作為ORM領(lǐng)域標(biāo)準(zhǔn)化整合者的目標(biāo)應(yīng)該不難實(shí)現(xiàn)。
JPA通過(guò)JDK 5.0注解或XML描述對(duì)象-關(guān)系表的映射關(guān)系,并將運(yùn)行期的實(shí)體對(duì)象持久化到數(shù)據(jù)庫(kù)中。
Sun引入新的JPA ORM規(guī)范出于兩個(gè)原因:
其一,簡(jiǎn)化現(xiàn)有Java EE和Java SE應(yīng)用的對(duì)象持久化的開(kāi)發(fā)工作;
其二,Sun希望整合對(duì)ORM技術(shù),實(shí)現(xiàn)天下歸一。
JPA由EJB 3.0軟件專(zhuān)家組開(kāi)發(fā),作為JSR-220實(shí)現(xiàn)的一部分。
但它不囿于EJB 3.0,你可以在Web應(yīng)用、甚至桌面應(yīng)用中使用。
JPA的宗旨是為POJO提供持久化標(biāo)準(zhǔn)規(guī)范,由此可見(jiàn),經(jīng)過(guò)這幾年的實(shí)踐探索,能夠脫離容器獨(dú)立運(yùn)行,方便開(kāi)發(fā)和測(cè)試的理念已經(jīng)深入人心了。
目前Hibernate 3.2、TopLink 10.1.3以及OpenJpa都提供了JPA的實(shí)現(xiàn)。
JPA的總體思想和現(xiàn)有Hibernate、TopLink,JDO等ORM框架大體一致。
總的來(lái)說(shuō),JPA包括以下3方面的技術(shù):
1、ORM映射元數(shù)據(jù),JPA支持XML和JDK 5.0注解兩種元數(shù)據(jù)的形式,元數(shù)據(jù)描述對(duì)象和表之間的映射關(guān)系,框架據(jù)此將實(shí)體對(duì)象持久化到數(shù)據(jù)庫(kù)表中;
2、JPA 的API,用來(lái)操作實(shí)體對(duì)象,執(zhí)行CRUD操作,框架在后臺(tái)替我們完成所有的事情,開(kāi)發(fā)者從繁瑣的JDBC和SQL代碼中解脫出來(lái)。
3、查詢(xún)語(yǔ)言,這是持久化操作中很重要的一個(gè)方面,通過(guò)面向?qū)ο蠖敲嫦驍?shù)據(jù)庫(kù)的查詢(xún)語(yǔ)言查詢(xún)數(shù)據(jù),避免程序的SQL語(yǔ)句緊密耦合。
2、實(shí)體對(duì)象
訪問(wèn)數(shù)據(jù)庫(kù)前,我們總是要設(shè)計(jì)在應(yīng)用層承載數(shù)據(jù)的領(lǐng)域?qū)ο螅―omain Object),ORM框架將它們持久化到數(shù)據(jù)庫(kù)表中。
為了方便后面的講解,我們用論壇應(yīng)用為例,建立領(lǐng)域?qū)ο螅?/p>
Topic -----(extends)----> PollTopic 1--------------*> PollOption
Topic是論壇的主題,而PollTopic是調(diào)查性質(zhì)的論壇主題,擴(kuò)展于Topic,一個(gè)調(diào)查主題擁有多個(gè)選項(xiàng)PollOption。
這三個(gè)領(lǐng)域?qū)ο蠛芎玫卣宫F(xiàn)了領(lǐng)域?qū)ο笾g繼承和關(guān)聯(lián)這兩大核心的關(guān)系。這3個(gè)領(lǐng)域?qū)ο髮⒈挥成涞綌?shù)據(jù)庫(kù)的兩張表中:
T_topic代碼
topic_id id <pk>
topic_title varchar(100)
topic_time datetime
topic_views int
topic_type tinyint
multiple tinyint
max_choice tinyint
T_polloption代碼
option_id int <pk>
topic_id int
votes int
displayorder tinyint
option varchar(80)
其中,Topic及其子類(lèi)PollTopic將映射到同一張t_topic表中,并用topic_type字段區(qū)分兩者。而PollOption映射到t_polloption中。
具有ORM元數(shù)據(jù)的領(lǐng)域?qū)ο蠓Q(chēng)為實(shí)體(Entity),按JPA的規(guī)范,實(shí)體具備以下的條件:
1、必須使用javax.persistence.Entity注解或者在XML映射文件中有對(duì)應(yīng)的元素;
2、必須具有一個(gè)不帶參的構(gòu)造函數(shù),類(lèi)不能聲明為final,方法和需要持久化的屬性也不能聲明為final;
3、如果游離狀的實(shí)體對(duì)象需要以值的方式進(jìn)行傳遞,如通Session bean的遠(yuǎn)程業(yè)務(wù)接口傳遞,則必須實(shí)現(xiàn)Serializable接口;
4、需要持久化的屬性,其訪問(wèn)修飾符不能是public,它們必須通過(guò)實(shí)體類(lèi)方法進(jìn)行訪問(wèn)。
3.使用注解元數(shù)據(jù)
@Entity:
將領(lǐng)域?qū)ο髽?biāo)注為一個(gè)實(shí)體,表示需要保存到數(shù)據(jù)庫(kù)中,默認(rèn)情況下類(lèi)名即為表名,通過(guò)name屬性顯式指定表名,如name = "T_TOPIC",表示Topic保存到T_TOPIC表中;
@Id :
對(duì)應(yīng)的屬性是表的主鍵;
@GeneratedValue:
主鍵的產(chǎn)生策略,通過(guò)strategy屬性指定。默認(rèn)情況下,JPA自動(dòng)選擇一個(gè)最適合底層數(shù)據(jù)庫(kù)的主鍵生成策略:
如SqlServer對(duì)應(yīng)identity,MySql對(duì)應(yīng)auto increment。
在javax.persistence.GenerationType中定義了以下幾種可供選擇的策略:
1) IDENTITY:表自增鍵字段,Oracle不支持這種方式;
2) AUTO: JPA自動(dòng)選擇合適的策略,是默認(rèn)選項(xiàng);
3) SEQUENCE:通過(guò)序列產(chǎn)生主鍵,通過(guò)@SequenceGenerator注解指定序列名,MySql不支持這種方式;
4) TABLE:通過(guò)表產(chǎn)生主鍵,框架借由表模擬序列產(chǎn)生主鍵,使用該策略可以使應(yīng)用更易于數(shù)據(jù)庫(kù)移植。
不同的JPA實(shí)現(xiàn)商生成的表名是不同的:
如 OpenJPA生成openjpa_sequence_table表
Hibernate生成一個(gè)hibernate_sequences表,
而TopLink則生成sequence表。這些表都具有一個(gè)序列名和對(duì)應(yīng)值兩個(gè)字段,如SEQ_NAME和SEQ_COUNT。
@Column(name = "TOPIC_ID"):
屬性對(duì)應(yīng)的表字段。我們并不需要指定表字段的類(lèi)型,因?yàn)镴PA會(huì)根據(jù)反射從實(shí)體屬性中獲取類(lèi)型;如果是字符串類(lèi)型,我們可以指定字段長(zhǎng)度,以便可以自動(dòng)生成DDL語(yǔ)句;
@Temporal(TemporalType.DATE):
如果屬性是時(shí)間類(lèi)型,因?yàn)閿?shù)據(jù)表對(duì)時(shí)間類(lèi)型有更嚴(yán)格的劃分,所以必須指定具體時(shí)間類(lèi)型。在javax.persistence.TemporalType枚舉中定義了3種時(shí)間類(lèi)型:
1) DATE :等于java.sql.Date
2) TIME :等于java.sql.Time
3) TIMESTAMP :等于java.sql.Timestamp
繼承關(guān)系
Topic和PollTopic是父子類(lèi),JPA 采用多種方法來(lái)支持實(shí)體繼承。在父類(lèi)中必須聲明繼承實(shí)體的映射策略。
對(duì)于繼承的實(shí)體,在javax.persistence.InheritanceType定義了3種映射策略:
SINGLE_TABLE:
父子類(lèi)都保存到同一個(gè)表中,通過(guò)字段值進(jìn)行區(qū)分。這是我們Topic實(shí)體所采用的策略,
Topic和PollTopic都保存到同一張表中,通過(guò)TOPIC_TYPE字段進(jìn)行區(qū)分,Topic在T_TOPIC表中對(duì)應(yīng)TOPIC_TYPE= 1的記錄,而PollTopic對(duì)應(yīng)TOPIC_TYPE=2的記錄(稍后在PollTopic實(shí)體中指定);
區(qū)別的字段通過(guò) @DiscriminatorColumn 說(shuō)明,區(qū)分字段對(duì)應(yīng)該實(shí)體的值通過(guò)@DiscriminatorValue 指定;
JOINED:
父子類(lèi)相同的部分保存在同一個(gè)表中,不同的部分分開(kāi)存放,通過(guò)表連接獲取完整數(shù)據(jù);
TABLE_PER_CLASS:
每一個(gè)類(lèi)對(duì)應(yīng)自己的表,一般不推薦采用這種方式。
Java代碼
@DiscriminatorColumn(name = "TOPIC_TYPE", discriminatorType =DiscriminatorType.INTEGER, length = 1) ②
@DiscriminatorValue(value="1")③
關(guān)聯(lián)關(guān)系
JPA規(guī)范規(guī)定任何屬性都默認(rèn)映射到表中,所以雖然我們沒(méi)有給multiple屬性提供注解信息,但JPA將按照默認(rèn)的規(guī)則對(duì)該字段進(jìn)行映射:字段名和屬性名相同,類(lèi)型相同。
如果我們不希望將某個(gè)屬性持久化到數(shù)據(jù)表中,則可以通過(guò) @Transient 注解顯式指定: @Transient
我們通過(guò)@OneToMany 指定了一個(gè)一對(duì)多的關(guān)聯(lián)關(guān)系,一個(gè)PollTopic包括多個(gè) PollOption對(duì)象(我們將在稍后的PollOption中通過(guò)ManyToOne描述PollOption和PollTopic的關(guān)系,以建立 PollTopic和PollOption的雙向關(guān)聯(lián)關(guān)系)。
Java代碼
@OneToMany(mappedBy="pollTopic",cascade=CascadeType.ALL) ④
private Set options = new HashSet();
@OneToMany 中通過(guò)mappedBy屬性指定“Many”方類(lèi)引用“One”方類(lèi)的屬性名,這里mappedBy="pollTopic"表示PollOption實(shí)體擁有一個(gè)指定PollTopic的pollTopic屬性。
Java代碼
@ManyToOne ①
@JoinColumn(name="TOPIC_ID", nullable=false) ②
private PollTopic pollTopic;
在①處通過(guò)@ManyToOne描述了PollOption和PollTopic的多對(duì)一關(guān)聯(lián)關(guān)系,并通過(guò)@JoinColumn指定關(guān)聯(lián)PollTopic實(shí)體所對(duì)應(yīng)表的“外鍵”,如②所示。
Lob字段
在JPA中Lob類(lèi)型類(lèi)型的持久化很簡(jiǎn)單,僅需要通過(guò)特殊的Lob注解就可以達(dá)到目的。下面,我們對(duì)Post中的Lob屬性類(lèi)型進(jìn)行標(biāo)注:
Java代碼
@Lob ①-1
@Basic(fetch = FetchType.EAGER) ①-2
@Column(name = "POST_TEXT", columnDefinition = "LONGTEXT NOT NULL") ①-3
private String postText;
postText屬性對(duì)應(yīng)T_POST表的POST_TEXT字段,該字段的類(lèi)型是LONTTEXT,并且非空。
JPA 通過(guò)@Lob將屬性標(biāo)注為L(zhǎng)ob類(lèi)型,如①-1和②-1所示。
通過(guò)@Basic指定Lob類(lèi)型數(shù)據(jù)的獲取策略,F(xiàn)etchType.EAGER表示非延遲加載,而FetchType. LAZY表示延遲加載,如①-2和②-2所示。
通過(guò)@Column的columnDefinition屬性指定數(shù)據(jù)表對(duì)應(yīng)的Lob字段類(lèi)型,如①-3和② -3所示。
1. JPA概念Java persistence API的簡(jiǎn)稱(chēng),中文名是Java持久層API,是JDK5.0注解或XML描述對(duì)象-關(guān)系表的映射關(guān)系,并將運(yùn)行期的實(shí)體對(duì)象持久化到數(shù)據(jù)庫(kù)中。
2. JPA出現(xiàn)的原因
1.簡(jiǎn)化現(xiàn)有JavaEE和JavaSE應(yīng)用的對(duì)象持久化的開(kāi)發(fā)工作;
2.Sun希望整合ORM技術(shù),實(shí)現(xiàn)在持久化領(lǐng)域的統(tǒng)一應(yīng)用;
3. JPA提供的技術(shù)1.ORM映射元數(shù)據(jù)JPA支持XML和JDK5.0注解兩種元數(shù)據(jù)的形式,元數(shù)據(jù)描述對(duì)象和表之間的映射關(guān)系框架據(jù)此將實(shí)體對(duì)象持久化到數(shù)據(jù)庫(kù)表中;2.JPA的API用來(lái)操作實(shí)體對(duì)象,執(zhí)行crud操作,框架在底層替我們完成所有的事情,開(kāi)發(fā)者從繁瑣的JDBC 和 SQL代碼中解脫;3.查詢(xún)語(yǔ)言通過(guò)面向?qū)ο蠖敲嫦驍?shù)據(jù)庫(kù)的查詢(xún)語(yǔ)言查詢(xún)數(shù)據(jù),避免程序的SQL語(yǔ)句緊密耦合;
JPA是Java Persistence API的簡(jiǎn)稱(chēng), 中文名為Java持久層API;
是JDK 5.0注解或XML描述對(duì)象-關(guān)系表的映射關(guān)系, 并將運(yùn)行期的實(shí)體對(duì)象持久化到數(shù)據(jù)庫(kù)中。
JPA包括以下3方面的內(nèi)容:
1) 一套API標(biāo)準(zhǔn)。
在javax.persistence的包下面, 用來(lái)操作實(shí)體對(duì)象, 執(zhí)行CRUD操作, 框架在后臺(tái)替代我們完成所有的事情, 開(kāi)發(fā)者從煩瑣的JDBC和SQL代碼中解脫出來(lái)。
2) 面向?qū)ο蟮牟樵?xún)語(yǔ)言: Java Persistence Query Language(JPQL) 。
這是持久化操作中很重要的一個(gè)方面, 通過(guò)面向?qū)ο蠖敲嫦驍?shù)據(jù)庫(kù)的查詢(xún)語(yǔ)言查詢(xún)數(shù)據(jù), 避免程序的SQL語(yǔ)句緊密耦合。
3) ORM(object/relational metadata) 元數(shù)據(jù)的映射。
JPA支持XML和JDK5.0注解兩種元數(shù)據(jù)的形式, 元數(shù)據(jù)描述對(duì)象和表之間的映射關(guān)系, 框架據(jù)此將實(shí)體對(duì)象持久化到數(shù)據(jù)庫(kù)表中。
總的來(lái)說(shuō):
jpa是用于對(duì)象持久化的API;
是jave EE5.0平臺(tái)的標(biāo)準(zhǔn)ORM規(guī)范,其作用是使得應(yīng)用程序以統(tǒng)一的方式來(lái)訪問(wèn)持久層;
目前主要使用的jap實(shí)現(xiàn)是hibernate;
JPA是Java Persistence API的簡(jiǎn)稱(chēng), 中文名為Java持久層API;
是JDK 5.0注解或XML描述對(duì)象-關(guān)系表的映射關(guān)系, 并將運(yùn)行期的實(shí)體對(duì)象持久化到數(shù)據(jù)庫(kù)中。
不是國(guó)家的名稱(chēng)
1.jpa的介紹
JPA是Java Persistence API的簡(jiǎn)稱(chēng), 中文名為Java持久層API;
是JDK 5.0注解或XML描述對(duì)象-關(guān)系表的映射關(guān)系, 并將運(yùn)行期的實(shí)體對(duì)象持久化到數(shù)據(jù)庫(kù)中。
JPA包括以下3方面的內(nèi)容:
1) 一套API標(biāo)準(zhǔn)。
在javax.persistence的包下面, 用來(lái)操作實(shí)體對(duì)象, 執(zhí)行CRUD操作, 框架在后臺(tái)替代我們完成所有的事情, 開(kāi)發(fā)者從煩瑣的JDBC和SQL代碼中解脫出來(lái)。
2) 面向?qū)ο蟮牟樵?xún)語(yǔ)言: Java Persistence Query Language(JPQL) 。
這是持久化操作中很重要的一個(gè)方面, 通過(guò)面向?qū)ο蠖敲嫦驍?shù)據(jù)庫(kù)的查詢(xún)語(yǔ)言查詢(xún)數(shù)據(jù), 避免程序的SQL語(yǔ)句緊密耦合。
3) ORM(object/relational metadata) 元數(shù)據(jù)的映射。
JPA支持XML和JDK5.0注解兩種元數(shù)據(jù)的形式, 元數(shù)據(jù)描述對(duì)象和表之間的映射關(guān)系, 框架據(jù)此將實(shí)體對(duì)象持久化到數(shù)據(jù)庫(kù)表中。
總的來(lái)說(shuō):
jpa是用于對(duì)象持久化的API;
是jave EE5.0平臺(tái)的標(biāo)準(zhǔn)ORM規(guī)范,其作用是使得應(yīng)用程序以統(tǒng)一的方式來(lái)訪問(wèn)持久層;
目前主要使用的jap實(shí)現(xiàn)是hibernate;
應(yīng)該是Ipa吧。
IPA是現(xiàn)在最流行的一種精釀啤酒的縮寫(xiě),India Pale Ale,翻譯為印度淡色艾爾,但是這種啤酒并非源自印度,而是源于英國(guó)。
按照BJCP的說(shuō)法,現(xiàn)代以美式為代表的IPA已經(jīng)和這個(gè)名字毫無(wú)關(guān)系了,IPA只是代表一類(lèi)以酒花味道為主的啤酒類(lèi)型。
JPA是Java Persistence API的簡(jiǎn)稱(chēng),中文名Java持久層API,是JDK 5.0注解或XML描述對(duì)象-關(guān)系表的映射關(guān)系,并將運(yùn)行期的實(shí)體對(duì)象持久化到數(shù)據(jù)庫(kù)中。
Sun引入新的JPA ORM規(guī)范出于兩個(gè)原因:其一,簡(jiǎn)化現(xiàn)有Java EE和Java SE應(yīng)用開(kāi)發(fā)工作;其二,Sun希望整合ORM技術(shù),實(shí)現(xiàn)天下歸一。
JPA優(yōu)勢(shì)
可持久化Java對(duì)象。JPA能夠直接持久化復(fù)雜的Java對(duì)象,并能夠使用JPQL語(yǔ)言進(jìn)行復(fù)雜的查詢(xún)。JPQL是JPA專(zhuān)用的查詢(xún)語(yǔ)言,是類(lèi)似于SQL的面向?qū)ο蟮牟樵?xún)語(yǔ)言。
使用簡(jiǎn)單。JPA使用注釋?zhuān)ˋnnotation)定義Java對(duì)象與關(guān)系數(shù)據(jù)庫(kù)之間的映射,而傳統(tǒng)的ORM多使用xml配置文件。JPA使用起來(lái)比ORM要方便。使用JPA不用關(guān)注底層使用什么數(shù)據(jù)庫(kù)。
規(guī)范標(biāo)準(zhǔn)化。JPA是JCP組織發(fā)布的,是Java官方規(guī)定的統(tǒng)一的API。目前已經(jīng)有多種框架實(shí)現(xiàn)JPA標(biāo)準(zhǔn)。使用了JPA的系統(tǒng)可以自由選擇遵循JPA標(biāo)準(zhǔn)的框架,并能夠自由更換。
事務(wù)性、大數(shù)據(jù)量。JPA底層使用關(guān)系數(shù)據(jù)庫(kù)進(jìn)行存儲(chǔ),因此具備關(guān)系數(shù)據(jù)庫(kù)的特點(diǎn),例如事務(wù)性、數(shù)據(jù)完整性、并發(fā)訪問(wèn)、大數(shù)據(jù)量等。
與其他持久化技術(shù)相比,JPA有很大的技術(shù)優(yōu)勢(shì)。表列出了JPA與其他持久化技術(shù)的比較。
JPA的劣勢(shì)
由于非常新,JPA 規(guī)范可能還需要進(jìn)過(guò)重要發(fā)展才會(huì)變得很穩(wěn)定。
JPA 是一個(gè)規(guī)范而不是一個(gè)產(chǎn)品。需要提供商提供一個(gè)實(shí)施,才能獲得這些基于標(biāo)準(zhǔn)的 API 的優(yōu)勢(shì)。
區(qū)別主要有以下幾點(diǎn)
1、 jpa和mybatis的反映對(duì)象不同
GPA是java persistence api的縮寫(xiě),它的中文翻譯就是指程序JAVA持久層API,Mybatis相對(duì)來(lái)說(shuō)比較實(shí)用的持久層框架。首先,兩者最大的不同就在于內(nèi)部的反應(yīng)對(duì)象,JPA的操作是在對(duì)象與對(duì)象之間的反射,而mybatis的處理對(duì)象是在對(duì)象和結(jié)果集合之間的反射。雖然其最終的持久層框架結(jié)果是一樣的,但是卻在操作過(guò)程中有千差萬(wàn)別。
2. jpa和mybatis的功能性質(zhì)不同
從整體的移植性來(lái)看,GPA的一致性相對(duì)較好,他在數(shù)據(jù)庫(kù)的兼容性基本都是相同的,所以不用擔(dān)心其他問(wèn)題。一般來(lái)說(shuō)springdatajpa都知道當(dāng)一個(gè)接口繼承了GPA,接口之后便會(huì)自動(dòng)具備數(shù)據(jù)移植的良好性質(zhì)。由于mybatis是使用SQL語(yǔ)句,所以在移植時(shí)必須將數(shù)據(jù)庫(kù)的類(lèi)型改為sql了。從這一點(diǎn)上來(lái)看,GPA更具優(yōu)勢(shì),其次在操作層面修改字段的時(shí)候,mybatis也相對(duì)操作步驟比較多。
3. jpa和mybatis操作流程不同
如果是學(xué)習(xí)操作持久層的話,用hibernate會(huì)比較麻煩,所以從具體學(xué)習(xí)操作來(lái)看,mybatis具有更強(qiáng)烈的優(yōu)勢(shì),同時(shí)也可以使用springdatajpa,但是這一種方式更適合于單表。但在這里可以發(fā)現(xiàn)這一篇a的妥協(xié)性,為了支持這一特性,但在實(shí)際操作起來(lái),并不推薦薦使用,因?yàn)檫@種操作方式并不符合領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的目標(biāo)和理念。
Spring Data JPA項(xiàng)目的版本1.0.1和1.1.0.M1已發(fā)布。