国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
JPA重整ORM山河
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ù)中,圖 1很好地描述了JPA的結(jié)構(gòu):
·官方下載:XP 2006新春桌面主題
·QQ2006 界面編程之雞蛋里挑骨頭
·張揚(yáng)聊天個(gè)性:群英會(huì)2006正式版評(píng)測(cè)
·AMD董事長(zhǎng)魯毅智2006年薪酬1610萬(wàn)美元
·教你玩轉(zhuǎn)PP2006
·為你搜羅2006年值得推薦的日語(yǔ)學(xué)習(xí)軟
·2006:瀏覽器進(jìn)入多元化發(fā)展
·盤(pán)點(diǎn):2006歲末IT業(yè)界大事狂PK
·總結(jié)2006:十大Windows恢復(fù)技巧
·2006年優(yōu)秀網(wǎng)頁(yè)UI設(shè)計(jì)風(fēng)格特征剖析
 
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ù):
ORM映射元數(shù)據(jù),JPA支持XML和JDK 5.0注解兩種元數(shù)據(jù)的形式,元數(shù)據(jù)描述對(duì)象和表之間的映射關(guān)系,框架據(jù)此將實(shí)體對(duì)象持久化到數(shù)據(jù)庫(kù)表中;
JPA 的API,用來(lái)操作實(shí)體對(duì)象,執(zhí)行CRUD操作,框架在后臺(tái)替我們完成所有的事情,開(kāi)發(fā)者從繁瑣的JDBC和SQL代碼中解脫出來(lái)。
查詢(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ū)ο螅?div style="height:15px;">
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ù)的兩張表中:
其中,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í)體具備以下的條件:
必須使用javax.persistence.Entity注解或者在XML映射文件中有對(duì)應(yīng)的元素;
必須具有一個(gè)不帶參的構(gòu)造函數(shù),類(lèi)不能聲明為final,方法和需要持久化的屬性也不能聲明為final;
如果游離狀的實(shí)體對(duì)象需要以值的方式進(jìn)行傳遞,如通Session bean的遠(yuǎn)程業(yè)務(wù)接口傳遞,則必須實(shí)現(xiàn)Serializable接口;
需要持久化的屬性,其訪問(wèn)修飾符不能是public,它們必須通過(guò)實(shí)體類(lèi)方法進(jìn)行訪問(wèn)。
基本注解
首先,我們對(duì)Topic領(lǐng)域?qū)ο筮M(jìn)行注解,使其成為一個(gè)合格的實(shí)體類(lèi):
代碼清單1:Topic實(shí)體類(lèi)的注解
package com.baobaotao.domain;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity(name = "T_TOPIC") ①
public class Topic implements Serializable ...{
@Id   ②-1
@GeneratedValue(strategy = GenerationType.TABLE) ②-2
@Column(name = "TOPIC_ID") ②-3
private int topicId;
@Column(name = "TOPIC_TITLE", length = 100) ③
private String topicTitle;
@Column(name = "TOPIC_TIME")
@Temporal(TemporalType.DATE) ④
private Date topicTime;
@Column(name = "TOPIC_VIEWS")
private int topicViews;
//省略get/setter方法
}
@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)的屬性是表的主鍵,如②-1所示;
@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í)體的映射策略,如代碼清單2所示:
代碼清單2:繼承實(shí)體的映射策略
@Entity(name = "T_TOPIC")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) ①
@DiscriminatorColumn(name = "TOPIC_TYPE", discriminatorType =
DiscriminatorType.INTEGER, length = 1) ②
@DiscriminatorValue(value="1")③
public class Topic implements Serializable ...{
}
對(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)自己的表,一般不推薦采用這種方式。
關(guān)聯(lián)關(guān)系
我們?cè)倮^續(xù)對(duì)PollTopic進(jìn)行注解,進(jìn)一步了解實(shí)體繼承的JPA映射定義:
代碼清單3:PollTopic映射描述
package com.baobaotao.domain;
@Entity
@DiscriminatorValue(value="2") ①
public class PollTopic extends Topic ...{②繼承于Topic實(shí)體
private boolean multiple; ③
@Column(name = "MAX_CHOICES")
private int maxChoices;
@OneToMany(mappedBy="pollTopic",cascade=CascadeType.ALL) ④
private Set options = new HashSet ();
//省略get/setter方法
}
在①處,通過(guò)@DiscriminatorValue將區(qū)分字段TOPIC_TYPE的值為2。由于PollTopic實(shí)體繼承于Topic實(shí)體,其它的元數(shù)據(jù)信息直接從Topic獲得。
JPA規(guī)范規(guī)定任何屬性都默認(rèn)映射到表中,所以雖然我們沒(méi)有給③處的multiple屬性提供注解信息,但JPA將按照默認(rèn)的規(guī)則對(duì)該字段進(jìn)行映射:字段名和屬性名相同,類(lèi)型相同。如果我們不希望將某個(gè)屬性持久化到數(shù)據(jù)表中,則可以通過(guò)@Transient注解顯式指定:
@Transient
private boolean tempProp1;
在④處,我們通過(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)系)。
@OneToMany中通過(guò)mappedBy屬性指定“Many”方類(lèi)引用“One”方類(lèi)的屬性名,這里mappedBy="pollTopic"表示PollOption實(shí)體擁有一個(gè)指定PollTopic的pollTopic屬性。
下面,我們來(lái)看一下Many方PollOption實(shí)體類(lèi)的映射描述:
代碼清單4:PollOption映射描述
package com.baobaotao.domain;
@Entity(name="T_POLL_OPTION")
public class PollOption implements Serializable ...{
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "OPTION_ID")
private int optionId;
@Column(name = "OPTION_ITEM")
private String optionItem;
@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)表的“外鍵”,如②所示。
當(dāng)然也可以通過(guò)@OneToOne和@ManyToMany指定一對(duì)一和多以多的關(guān)系,方法差不多,不再贅述。
Lob字段
在JPA中Lob類(lèi)型類(lèi)型的持久化很簡(jiǎn)單,僅需要通過(guò)特殊的Lob注解就可以達(dá)到目的。下面,我們對(duì)Post中的Lob屬性類(lèi)型進(jìn)行標(biāo)注:
代碼清單5 Post:標(biāo)注Lob類(lèi)型屬性
package com.baobaotao.domain;
import javax.persistence.Basic;
import javax.persistence.Lob;
@Entity(name = "T_POST")
public class Post implements Serializable ...{
@Lob ①-1
@Basic(fetch = FetchType.EAGER) ①-2
@Column(name = "POST_TEXT", columnDefinition = "LONGTEXT NOT NULL") ①-3
private String postText;
@Lob ②-1
@Basic(fetch = FetchType. LAZY) ②-2
@Column(name = "POST_ATTACH", columnDefinition = "BLOB") ②-3
private byte[] postAttach;
}
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所示。
關(guān)于JPA注解的更多信息,你可以通過(guò)這篇文章進(jìn)行更加深入的學(xué)習(xí):http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-annotations.html
4.使用XML元數(shù)據(jù)
除了使用注解提供元數(shù)據(jù)信息外,JPA也允許我們通過(guò)XML提供元數(shù)據(jù)信息。條條道路通羅馬,路路都是安康道,開(kāi)發(fā)者安全可以根據(jù)自己的習(xí)慣喜好擇一而從。按照J(rèn)PA的規(guī)范,如果你提供了XML元數(shù)據(jù)描述信息,它將覆蓋實(shí)體類(lèi)中的注解元數(shù)據(jù)信息。XML元數(shù)據(jù)信息以orm.xml命名,放置在類(lèi)路徑的META-INF目錄下。
JPA盡量讓XML和注解的元數(shù)據(jù)在描述的結(jié)構(gòu)上相近,降低學(xué)習(xí)曲線和轉(zhuǎn)換難度,所以我們?cè)趯W(xué)習(xí)注解元數(shù)據(jù)后,學(xué)習(xí)XML元數(shù)據(jù)變得非常簡(jiǎn)單。下面,我們給出以上實(shí)體的XML描述版本,你可以對(duì)照注解的描述進(jìn)行比較學(xué)習(xí):
代碼清單6 XML元數(shù)據(jù)配置:orm.xml
com.baobaotao.domain
②Topic實(shí)體配置
DATE
②PollTopic實(shí)體配置
2
②PollOption實(shí)體配置
②Post實(shí)體配置
 
從代碼清單6中,我們可以看出PollTopic并不需要通過(guò)特殊配置指定和Topic的繼承關(guān)系,這些信息將從實(shí)體類(lèi)反射信息獲取。所以從嚴(yán)格意義上來(lái)說(shuō),元數(shù)據(jù)信息或XML和實(shí)體類(lèi)結(jié)構(gòu)信息共同構(gòu)成的。
5.JPA的編程結(jié)構(gòu)及重要的API
JavaEE 5.0中所定義的JPA接口個(gè)數(shù)并不多,它們位于javax.persistence和javax.persistence.spi兩個(gè)包中。javax.persistence包中大部分API都是注解類(lèi),除此之外還包括EntityManager、Query等持久化操作接口。而javax.persistence.spi包中的4個(gè)API,是JPA的服務(wù)層接口。下面,我們就來(lái)認(rèn)識(shí)一下這些重要的接口。
EntityManager的類(lèi)型
實(shí)體對(duì)象由實(shí)體管理器進(jìn)行管理,JPA使用javax.persistence.EntityManager代表實(shí)體管理器。實(shí)體管理器和持久化上下文關(guān)聯(lián),持久化上下文是一系列實(shí)體的管理環(huán)境,我們通過(guò)EntityManager和持久化上下文進(jìn)行交互。
有兩種類(lèi)型的實(shí)體管理器
容器型:容器型的實(shí)體管理器由容器負(fù)責(zé)實(shí)體管理器之間的協(xié)作,在一個(gè)JTA事務(wù)中,一個(gè)實(shí)體管理器的持久化上下文的狀態(tài)會(huì)自動(dòng)廣播到所有使用EntityManager的應(yīng)用程序組件中。Java EE應(yīng)用服務(wù)器提供的就是管理型的實(shí)體管理器;
應(yīng)用程序型:實(shí)體管理器的生命周期由應(yīng)用程序控制,應(yīng)用程序通過(guò)javax.persistence.EntityManagerFactory的createEntityManager創(chuàng)建EntityManager實(shí)例。
 
EntityManager的創(chuàng)建過(guò)程 javax.persistence.spi.PersistenceProvider接口由JPA的實(shí)現(xiàn)者提供,該接口由啟動(dòng)者調(diào)用,以便創(chuàng)建一個(gè)EntityManagerFactory實(shí)例。它定義了創(chuàng)建一個(gè)EntityManagerFactory實(shí)例的方法:
EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map)
javax.persistence.spi.PersistenceUnitInfo入?yún)⑻峁┝藙?chuàng)建實(shí)體管理器所需要的所有信息,這些信息根據(jù)JPA的規(guī)范,必須放置在META-INF/persistence.xml文件中。
PersistenceUnitInfo接口擁有了一個(gè)void addTransformer(ClassTransformer transformer)方法,通過(guò)該方式可以添加一個(gè)javax.persistence.spi.ClassTransformer,并通過(guò)PersistenceProvider開(kāi)放給容器,以便容器在實(shí)體類(lèi)文件加載到JVM之前進(jìn)行代碼的增強(qiáng),使元數(shù)據(jù)生效。JPA廠商負(fù)責(zé)提供ClassTransformer接口的實(shí)現(xiàn)。
圖4描述了創(chuàng)建EntityManager的過(guò)程:
點(diǎn)擊查看大圖
實(shí)體的狀態(tài)
實(shí)體%A
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
OpenJPA的基礎(chǔ)
JPA入門(mén)例子(采用JPA的hibernate實(shí)現(xiàn)版本)
Spring Boot Data JPA – 不將實(shí)體保存到數(shù)據(jù)庫(kù)
hibernate+jpa
JPA persistence.xml基本的配置
WebSphere 7 & javax/persistence/OneToMany.orp...
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服