慢慢來(lái)比較快,虛心學(xué)技術(shù)
原文鏈接:《Spring實(shí)戰(zhàn)》-第十一章:利用對(duì)象-關(guān)系映射持久化數(shù)據(jù)
一、什么是對(duì)象-關(guān)系映射(ORM)/為什么需要對(duì)象-關(guān)系映射
先來(lái)了解幾個(gè)概念:
- 瞬時(shí)狀態(tài):在程序運(yùn)行的時(shí)候,有些數(shù)據(jù)保存在內(nèi)存中,當(dāng)程序退出后,這些數(shù)據(jù)就不復(fù)存在了,稱這些數(shù)據(jù)的狀態(tài)是瞬時(shí)的。
- 持久狀態(tài):數(shù)據(jù)以文件形式保存在輔存中,這樣,程序退出后,數(shù)據(jù)依然存在,這種狀態(tài)稱之為持久的。
- 持久化 :即在程序中的瞬時(shí)狀態(tài)和持久狀態(tài)之間轉(zhuǎn)換的機(jī)制。
實(shí)際上,我們通常所說(shuō)的持久化,一般指的持久化數(shù)據(jù)到數(shù)據(jù)庫(kù)中。
在數(shù)據(jù)持久化的世界里面,傳統(tǒng)的dao已經(jīng)很難滿足開發(fā)的需求,或者顯得過(guò)于臃腫耦合,程序代碼中存在大量的問(wèn)號(hào)字符串(SQL語(yǔ)句)。那么,使用對(duì)象-關(guān)系映射將對(duì)象屬性映射到數(shù)據(jù)庫(kù)表的列字段,從而實(shí)現(xiàn)操作對(duì)象以操作數(shù)據(jù)記錄,簡(jiǎn)化代碼就很有必要了,同時(shí)我們還需要學(xué)習(xí)用到幾個(gè)特性:
- 延遲加載( Lazy loading ):隨著我們的對(duì)象關(guān)系變得越來(lái)越復(fù)雜,有時(shí)候我們并不希望立即獲取完整的對(duì)象間關(guān)系。舉一個(gè)典型的例子,假設(shè)我們?cè)诓樵円唤M PurchaseOrder 對(duì)象,而每個(gè)對(duì)象中都包含一個(gè) LineItem 對(duì)象集合。如果我們只關(guān)心 PurchaseOrder 的屬性,那查詢出 LineItem 的數(shù)據(jù)就毫無(wú)意義。而且這可能是開銷很大的操作。延遲加載允許我們只在需要的時(shí)候獲取數(shù)據(jù)。
- 預(yù)先抓?。?Eager fetching ):這與延遲加載是相對(duì)的。借助于預(yù)先抓取,我們可以使用一個(gè)查詢獲取完整的關(guān)聯(lián)對(duì)象。如果我們需要 PurchaseOrder 及其關(guān)聯(lián)的 LineItem 對(duì)象,預(yù)先抓取的功能可以在一個(gè)操作中將它們?nèi)繌臄?shù)據(jù)庫(kù)中取出來(lái),節(jié)省了多次查詢的成本。
- 級(jí)聯(lián)( Cascading ):有時(shí),更改數(shù)據(jù)庫(kù)中的表會(huì)同時(shí)修改其他表?;氐轿覀冇嗁?gòu)單的例子中,當(dāng)刪除 Order 對(duì)象時(shí),我們希望同時(shí)在數(shù)據(jù)庫(kù)中刪除關(guān)聯(lián)的 LineItem 。
一些可用框架提供了上述服務(wù),這些服務(wù)的通用名稱是對(duì)象 / 關(guān)系映射( object-relational mapping , ORM )。在持久層使用 ORM 工具,可
以節(jié)省數(shù)千行的代碼和大量的開發(fā)時(shí)間。 ORM 工具能夠把你的注意力從容易出錯(cuò)的 SQL 代碼轉(zhuǎn)向如何實(shí)現(xiàn)應(yīng)用程序的真正需求。
二、Spring對(duì)ORM框架的支持與擴(kuò)展
Spring對(duì)多個(gè)持久化框架的集成提供了支持,這些框架包括
Hibernate:可能是最常用的ORM框架,是一個(gè)全自動(dòng)的orm框架,hibernate可以自動(dòng)生成SQL語(yǔ)句,自動(dòng)執(zhí)行,使得Java程序員可以隨心所欲的使用對(duì)象編程思維來(lái)操縱數(shù)據(jù)庫(kù)。
iBATIS:Apache推出的一種輕量級(jí)的對(duì)象關(guān)系映射(ORM)框架
Java數(shù)據(jù)對(duì)象( Java Data Objects , JDO ): 是一個(gè)應(yīng)用程序接口(API),它是Java程序員能夠間接地訪問(wèn)數(shù)據(jù)庫(kù),也就是說(shuō),不需使用直接的結(jié)構(gòu)化查詢語(yǔ)言(SQL)語(yǔ)句。JDO是作為Java數(shù)據(jù)庫(kù)連接(JDBC)的一個(gè)補(bǔ)充來(lái)介紹的,而JDBC是一個(gè)支持使用SOL語(yǔ)句對(duì)流行的數(shù)據(jù)庫(kù)程序進(jìn)行訪問(wèn)的接口。有了 JDO,程序員就可以使用類來(lái)定義數(shù)據(jù)對(duì)象,然后支撐程序就會(huì)根據(jù)類的定義來(lái)管理對(duì)給定數(shù)據(jù)庫(kù)的實(shí)際的數(shù)據(jù)訪問(wèn)了。
Java持久化 API ( Java Persistence API , JPA ):JAVA 持久化API,是EJB 3.0 的專家推出,作為 JSR-220的一部分,簡(jiǎn)單點(diǎn)來(lái)說(shuō)可以理解為是一個(gè)JAVA的標(biāo)準(zhǔn)規(guī)范,這個(gè)規(guī)范為對(duì)JAVA對(duì)象的持久化制定了一些標(biāo)準(zhǔn)的接口,也可以說(shuō),JPA****是一個(gè)標(biāo)準(zhǔn)的ORM(對(duì)象關(guān)系映射)規(guī)范,提出這個(gè)規(guī)范,一方面是為了簡(jiǎn)化EJB中對(duì)于對(duì)象持久化的操作,另一方面,也希望通過(guò)制定統(tǒng)一規(guī)范,達(dá)到一統(tǒng)ORM標(biāo)準(zhǔn)的目的
除了對(duì)這些框架提供集成支持,Spring還提供了額外的擴(kuò)展增強(qiáng)服務(wù):
- 支持集成 Spring 聲明式事務(wù);
- 透明的異常處理;
- 線程安全的、輕量級(jí)的模板類;
- DAO 支持類;
- 資源管理
三、JPA框架分析
簡(jiǎn)單來(lái)說(shuō),JPA只是一套規(guī)范,用于統(tǒng)一對(duì)象持久化操作的標(biāo)準(zhǔn)。其架構(gòu)組成如下:
JPA的主要組成封裝于Javax.persistence.jar包中:
- Persistence****:主要提供靜態(tài)方法獲取EntityManagerFactory實(shí)例
- EntityManagerFactory****:作為EntityMannage的工廠類,用于生產(chǎn)并管理多個(gè)EntityManager
- EntityManager****:****管理持久化對(duì)象,作為數(shù)據(jù)庫(kù)操作的接口
- EntityTransaction****:用于管理EntityManager操作,每個(gè)EntityManager對(duì)應(yīng)一個(gè)EntityTransaction
- Query****:由JPA供應(yīng)商提供,能夠獲取一個(gè)標(biāo)準(zhǔn)的關(guān)系對(duì)象并執(zhí)行數(shù)據(jù)庫(kù)操作
- Entity****:持久化對(duì)象/實(shí)體