JPA概要

本文最新版已更新至:http://thinkinside.tk/2012/12/30/JPA.html

JPA定義了Java ORM及實體操作API的標準。本文摘錄了JPA的一些關鍵信息以備查閱。

如果有hibernate的基礎,通過本文也可以快速掌握JPA的基本概念及使用。

Table of Contents

  • 1 JPA概述
  • 2 實體生命周期
  • 3 實體關系映射(ORM)
    • 3.1 基本映射
    • 3.2 ID生成策略
    • 3.3 關聯關系
    • 3.4 繼承關系
  • 4 事件及監聽
  • 5 Query Language 查詢語言
    • 5.1 使用參數
    • 5.2 命名查詢
    • 5.3 排序
    • 5.4 聚合查詢
    • 5.5 更新和刪除
    • 5.6 更多
  • 6 事務管理

1?JPA概述

JPA(Java Persistence API,Java持久化API),定義了對象-關系映射(ORM)以及實體對象持久化的標準接口。

JPA是JSR-220(EJB3.0)規范的一部分,在JSR-220中規定實體對象(EntityBean)由JPA進行支持。

所以JPA不局限于EJB3.0,而是作為POJO持久化的標準規范,可以脫離容器獨立運行,開發和測試更加方便。

JPA在應用中的位置如下圖所示:

?

JPA維護一個Persistence Context(持久化上下文),在持久化上下文中維護實體的生命周期。主要包含三個方面的內容:

  1. ORM元數據。JPA支持annotion或xml兩種形式描述對象-關系映射。
  2. 實體操作API。實現對實體對象的CRUD操作。
  3. 查詢語言。約定了面向對象的查詢語言JPQL(Java Persistence Query Language)。

JPA的主要API都定義在javax.persistence包中。如果你熟悉Hibernate,可以很容易做出對應:

org.hibernatejavax.persistence說明
cfg.ConfigurationPersistence讀取配置信息
SessionFactoryEntityManagerFactory用于創建會話/實體管理器的工廠類
SessionEntityManager提供實體操作API,管理事務,創建查詢
TransactionEntityTransaction管理事務
QueryQuery執行查詢

2?實體生命周期

實體生命周期是JPA中非常重要的概念,描述了實體對象從創建到受控、從刪除到游離的狀態變換。對實體的操作主要就是改變實體的狀態。

JPA中實體的生命周期如下圖:

  1. New,新創建的實體對象,沒有主鍵(identity)值
  2. Managed,對象處于Persistence Context(持久化上下文)中,被EntityManager管理
  3. Detached,對象已經游離到Persistence Context之外,進入Application Domain
  4. Removed, 實體對象被刪除

EntityManager提供一系列的方法管理實體對象的生命周期,包括:

  1. persist, 將新創建的或已刪除的實體轉變為Managed狀態,數據存入數據庫。
  2. remove,刪除受控實體
  3. merge,將游離實體轉變為Managed狀態,數據存入數據庫。

如果使用了事務管理,則事務的commit/rollback也會改變實體的狀態。

3?實體關系映射(ORM)

3.1?基本映射

對象端數據庫端annotion可選annotion
ClassTable@Entity@Table(name="tablename")
propertycolumn@Column(name = "columnname")
propertyprimary key@Id@GeneratedValue 詳見ID生成策略
propertyNONE@Transient?

3.2?ID生成策略

ID對應數據庫表的主鍵,是保證唯一性的重要屬性。JPA提供了以下幾種ID生成策略

  1. GeneratorType.AUTO ,由JPA自動生成
  2. GenerationType.IDENTITY,使用數據庫的自增長字段,需要數據庫的支持(如SQL Server、MySQL、DB2、Derby等)
  3. GenerationType.SEQUENCE,使用數據庫的序列號,需要數據庫的支持(如Oracle)
  4. GenerationType.TABLE,使用指定的數據庫表記錄ID的增長 需要定義一個TableGenerator,在@GeneratedValue中引用。例如:

    @TableGenerator( name="myGenerator", table="GENERATORTABLE", pkColumnName = "ENTITYNAME", pkColumnValue="MyEntity", valueColumnName = "PKVALUE", allocationSize=1 )

    @GeneratedValue(strategy = GenerationType.TABLE,generator="myGenerator")

3.3?關聯關系

JPA定義了one-to-one、one-to-many、many-to-one、many-to-many 4種關系。

對于數據庫來說,通常在一個表中記錄對另一個表的外鍵關聯;對應到實體對象,持有關聯數據的一方稱為owning-side,另一方稱為inverse-side。

為了編程的方便,我們經常會希望在inverse-side也能引用到owning-side的對象,此時就構建了雙向關聯關系。 在雙向關聯中,需要在inverse-side定義mappedBy屬性,以指明在owning-side是哪一個屬性持有的關聯數據。

對關聯關系映射的要點如下:

關系類型Owning-SideInverse-Side
one-to-one@OneToOne@OneToOne(mappedBy="othersideName")
one-to-many / many-to-one@ManyToOne@OneToMany(mappedBy="xxx")
many-to-many@ManyToMany@ManyToMany(mappedBy ="xxx")

其中 many-to-many關系的owning-side可以使用@JoinTable聲明自定義關聯表,比如Book和Author之間的關聯表:

@JoinTable(name = "BOOKAUTHOR", joinColumns = { @JoinColumn(name = "BOOKID", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "AUTHORID", referencedColumnName = "id") })

關聯關系還可以定制延遲加載和級聯操作的行為(owning-side和inverse-side可以分別設置):

通過設置fetch=FetchType.LAZY 或 fetch=FetchType.EAGER來決定關聯對象是延遲加載或立即加載。

通過設置cascade={options}可以設置級聯操作的行為,其中options可以是以下組合:

  • CascadeType.MERGE 級聯更新
  • CascadeType.PERSIST 級聯保存
  • CascadeType.REFRESH 級聯刷新
  • CascadeType.REMOVE 級聯刪除
  • CascadeType.ALL 級聯上述4種操作

3.4?繼承關系

JPA通過在父類增加@Inheritance(strategy=InheritanceType.xxx)來聲明繼承關系。A支持3種繼承策略:

  1. 單表繼承(InheritanceType.SINGLETABLE),所有繼承樹上的類共用一張表,在父類指定(@DiscriminatorColumn)聲明并在每個類指定@DiscriminatorValue來區分類型。
  2. 類表繼承(InheritanceType.JOINED),父子類共同的部分公用一張表,其余部分保存到各自的表,通過join進行關聯。
  3. 具體表繼承(InheritanceType.TABLEPERCLASS),每個具體類映射到自己的表。

其中1和2能夠支持多態,但是1需要允許字段為NULL,2需要多個JOIN關系;3最適合關系數據庫,對多態支持不好。具體應用時根據需要取舍。

4?事件及監聽

通過在實體的方法上標注@PrePersist,@PostPersist等聲明即可在事件發生時觸發這些方法。

5?Query Language 查詢語言

JPA提供兩種查詢方式,一種是根據主鍵查詢,使用EntityManager的find方法:

T find(Class entityClass, Object primaryKey)

另一種就是使用JPQL查詢語言。JPQL是完全面向對象的,具備繼承、多態和關聯等特性,和hibernate HQL很相似。

使用EntityManager的createQuery方法:

Query createQuery(String qlString)

5.1?使用參數

可以在JPQL語句中使用參數。JPQL支持命名參數和位置參數兩種參數,但是在一條JPQL語句中所有的參數只能使用同一種類型。

舉例如下:

  • 命令參數

Query query = em.createQuery("select p from Person p where p.personid=:Id"); query.setParameter("Id",new Integer(1));

  • 位置參數

Query query = em.createQuery("select p from Person p where p.personid=?1"); query.setParameter(1,new Integer(1));

5.2?命名查詢

如果某個JPQL語句需要在多個地方使用,還可以使用@NamedQuery 或者 @NamedQueries在實體對象上預定義命名查詢。

在需要調用的地方只要引用該查詢的名字即可。

例如:

@NamedQuery(name="getPerson", query= "FROM Person WHERE personid=?1")

@NamedQueries({ @NamedQuery(name="getPerson1", query= "FROM Person WHERE personid=?1"), @NamedQuery(name="getPersonList", query= "FROM Person WHERE age>?1") })

Query query = em.createNamedQuery("getPerson");

5.3?排序

JPQL也支持排序,類似于SQL中的語法。例如: Query query = em.createQuery("select p from Person p order by p.age, p.birthday desc");

5.4?聚合查詢

JPQL支持AVG、SUM、COUNT、MAX、MIN五個聚合函數。例如:

Query query = em.createQuery("select max(p.age) from Person p"); Object result = query.getSingleResult(); String maxAge = result.toString();

5.5?更新和刪除

JPQL不僅用于查詢,還可以用于批量更新和刪除。

如:

Query query = em.createQuery("update Order as o set o.amount=o.amount+10"); //update 的記錄數 int result = query.executeUpdate();

Query query = em.createQuery("delete from OrderItem item where item.order in(from Order as o where o.amount<100)"); query.executeUpdate();

query = em.createQuery("delete from Order as o where o.amount<100"); query.executeUpdate();//delete的記錄數

5.6?更多

與SQL類似,JPQL還涉及到更多的語法,可以參考:http://docs.oracle.com/cd/E11035_01/kodo41/full/html/ejb3_langref.html

6?事務管理

JPA支持本地事務管理(RESOURCELOCAL)和容器事務管理(JTA),容器事務管理只能用在EJB/Web容器環境中。

事務管理的類型可以在persistence.xml文件中的“transaction-type”元素配置。

JPA中通過EntityManager的getTransaction()方法獲取事務的實例(EntityTransaction),之后可以調用事務的begin()、commit()、rollback()方法。

Date: 2012-12-30 16:46:29 CST

Author: Holbrook

Org version 7.8.11 with Emacs version 24

Validate XHTML 1.0

轉載于:https://www.cnblogs.com/holbrook/archive/2012/12/30/2839842.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/376956.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/376956.shtml
英文地址,請注明出處:http://en.pswp.cn/news/376956.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何配置能讓fiddler抓去https的請求?

1、打開fiddler&#xff0c;>>Tools>>Fiddler Options&#xff0c; 打開如圖所示的HTTPS配置項&#xff1a;點擊Export Rppt Certifica to Desktop :桌面上多了一個證書&#xff1a;下面就是將證書導入&#xff1a;點擊開始-運行&#xff0c;輸入&#xff1a;mmc,…

Redis對象的refcount與lru屬性(內存回收、對象共享、空轉時長)

本筆記參考《Redis設計與實現》 P84~P88 內存回收 Redis在對象系統中使用reference counting技術實現了內存回收機制。程序可以通過跟蹤對象的引用計數信息&#xff0c;在適當的時候自動釋放對象并進行內存回收。 typedef struct redisObject {// ...// 引用計數int refcoun…

【閑聊】Baidu Map,excellent !!!Diaoyv island is China 's

【釣魚島】釣魚島是中國的&#xff01;Diaoyu Islands are Chinas! 釣魚島は中國のアール! ————————————youngLaker轉載于:https://www.cnblogs.com/younglaker/archive/2012/12/31/2840190.html

08:vigenère密碼_密碼技術:Vigenére密碼,Playfair密碼,Hill密碼

08:vigenre密碼1)Vigenre密碼 (1) Vigenre Cipher) This technique is an example of Polyalphabetic Substitution technique which uses 26 Caesar ciphers make up the mono-alphabetic substitution rules which follow a count shifting mechanism from 0 to 25. That is,…

Redis的RDB文件與AOF文件

本筆記參考《Redis設計與實現》 P118 ~ P150 RDB文件 1、RDB文件用于保存和還原Redis服務器所有數據庫中的所有鍵值對數據 2、SAVE命令由服務器進程直接執行保存操作&#xff0c;該命令會阻塞服務器 3、BGSAVE命令由子進程執行保存操作&#xff0c;不會阻塞服務器 注意此時服…

eclipse擴容

eclipse擴容 -vmD:/jdk-6u17-windows-i586/jdk1.6.0_17/bin/javaw.exe-startupplugins/org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar-nlen_US--launcher.libraryplugins/org.eclipse.equinox.launcher.win32.win32.x86_1.1.200.v20120913-144807-productorg.eclipse…

node oauth2驗證_如何設置和使用護照OAuth Facebook身份驗證(第2部分)| Node.js

node oauth2驗證In my last article (How to set up and use passport OAuth Facebook Authentication (Section 1) | Node.js), we looked at another form of authentication called the OAuth authentication which involves sign in or signup using social media. 在我的上…

Python and Microsoft Word

國外網站看到的文章&#xff1a;Accessing Microsoft Word with Python follows the same syntax that we used for Excel. Let’s take a quick look at how to access Word.from time import sleep import win32com.client as win32RANGE range(3, 8)def word():word win32…

東哥讀書小記 之 《一個廣告人的自白》

掰著指頭一算&#xff0c;端午假期確實完成不少事情&#xff0c;過的太尼瑪充實鳥&#xff1a;去健身房2小時&#xff0c;且老夫的平板支撐終于能堅持超過1分鐘&#xff0c;普大喜奔有木有&#xff1b;給合租的室友買蛋糕過了個生日&#xff1b;去 去哪兒 參加W3ctech的技術交流…

Redis的文件事件與時間事件處理

目錄文件事件處理事件類型客戶端和服務端的通信過程時間事件處理執行器執行周期性事件作用事件的調度與執行文件事件處理 Redis基于Reactor模式開發了文件事件處理器。文件事件處理器以單線程方式運行&#xff0c;通過IO多路復用程序監聽多個套接字&#xff0c;實現了高性能網…

fisher-yates_使用Fisher-Yates隨機播放算法以O(n)時間隨機播放給定數組

fisher-yatesExample: 例&#xff1a; Say the input array is [1, 2 3, 4, 5 6, 7]After reshuffling it can be anything like[4, 3, 7, 2, 1, 5, 1]Our goal is that the reshuffling should be as random as possible. 我們的目標是&#xff0c;改組應盡可能地隨機。 The…

[分享]一些在 WPF/Silverlight 中應用 MVVM 模式時可能會有點用途的代碼

想來這個博客也已經有很久沒更新過了&#xff0c;新年新氣象&#xff0c;現在就開始寫新內容吧。 最初的起因 在最近的幾個月中我做的開發總是要跟 XAML 打交道&#xff0c;也就是 WPF 啊&#xff0c;Silverlight 啊&#xff0c;WF 啊這些。 在進行 WPF 和 Silverlight 開發的…

手機調用系統的拍照和裁剪功能,假設界面有輸入框EditText,在一些手機會出現點擊EditText會彈出輸入法,卻不能輸入的情況。...

1、拍照裁剪后 點擊EditText會彈出輸入法&#xff0c;卻不能輸入。可是點擊點一EdtiText就能夠輸入了&#xff0c;所以我就寫了一個看不見的EdtiText&#xff0c;切換焦點&#xff0c;這樣就攻克了這個奇怪的這問題&#xff0c;應該是android內部的問題。 這是網絡一個牛人留下…

Redis一個命令請求從發送到完成的步驟以及初始化服務器步驟

一個命令請求從發送到完成的步驟 如下&#xff1a; 1、客戶端將命令請求發送給服務器 當用戶在客戶端中鍵入一個命令請求時&#xff0c;客戶端會將這個命令請求轉換成協議格式&#xff0c;然后通過連接到服務器的套接字&#xff0c;將協議格式的命令請求發送給服務器。 2、服…

c打印行號和函數_使用C中的函數名稱,行號從任何函數打印錯誤消息

c打印行號和函數Sometimes, it is necessary to print some message on logic failure or anytime with the function name and line number, so that program can be debugged and fixed the issue. 有時&#xff0c;有必要在邏輯故障時或在任何時候使用功能名稱和行??號打印…

Linux SPI框架

水平有限&#xff0c;描述不當之處還請指出&#xff0c;轉載請注明出處http://blog.csdn.net/vanbreaker/article/details/7733476 Linux的SPI子系統采用主機驅動和外設驅動分離的思想&#xff0c;首先主機SPI控制器是一種平臺設備&#xff0c;因此它以platform的方式注冊進內…

dbms標識符無效_DBMS中的嵌套查詢,相關的嵌套查詢和集合比較運算符

dbms標識符無效嵌套查詢 (Nested Queries) A query embedded in a query. This type of relation is termed as Nested Query and the Embedded Query is termed as a subquery. 查詢中嵌入的查詢。 這種類型的關系稱為嵌套查詢&#xff0c;而嵌入式查詢稱為子查詢。 For exam…

重構——解決過長參數列表(long parameter list)

目錄1、Replace Param with Query2、Preserve Whole Object3、Introduce Param Object4、Remove Flag Argument5、Combine Functions into ClassReference當我們需要在超長函數中提煉子函數時&#xff0c;如果函數內有大量的參數和臨時變量&#xff0c;這將會對函數的提煉形成很…

C# 點點滴滴: out和ref

用c#很長一段時間了&#xff0c;不過基本是啥都不會&#xff0c;當C用的&#xff0c;作為寫單片機的&#xff0c;還是真心覺得C比較親切&#xff0c;呵呵。 不過總是要進步啊&#xff0c;慢慢積累唄&#xff0c;這次是寫一個CAN的上位機模板出來&#xff0c;以后的項目就要徹底…

css控制圖片最寬 最高值

.content img{width:expression_r(this.width > 500 && this.height < this.width ? 500:true);max-width:500px;height:expression_r(this.height >500 ? 500:true);max-height:500px; }轉載于:https://www.cnblogs.com/panlin/archive/2013/01/06/2848017…