什么是JPA
JPA是Java Persistence API的簡稱。
JPA作為 Java EE 5.0 平臺(tái)標(biāo)準(zhǔn)的 對(duì)象關(guān)系映射(ORM)規(guī)范
將得到所有Java EE服務(wù)器的支持。 Sun 這次吸取了之前 EJB 規(guī)范慘痛失敗的經(jīng)歷,在充分吸收現(xiàn)有ORM框架(如Hibernate)的基礎(chǔ)上,得到了一個(gè)易于使用、伸縮性強(qiáng)的 ORM 規(guī)范。
[if !supportLists]3.?[endif]從目前的開發(fā)社區(qū)的反應(yīng)上看
JPA受到了極大的支持和贊揚(yáng), JPA 作為 ORM 領(lǐng)域標(biāo)準(zhǔn)化整合者的目標(biāo)已經(jīng)實(shí)現(xiàn)。
為什么需要JPA
這個(gè)需要從Hibernate的起源說起。 Hibernate作者Gavin King發(fā)現(xiàn)以前寫JDBC的開發(fā)效率太低,特別在Java這種面向?qū)ο蟮恼Z言在與關(guān)系型數(shù)據(jù)庫之間的數(shù)據(jù)轉(zhuǎn)換太麻煩了。
于是開發(fā)出了Hibernate,他當(dāng)時(shí)的目標(biāo)是,只要是Java程序員,就算不懂SQL語句,也可以來操作數(shù)據(jù)庫。
Hibernate和JPA的關(guān)系
Hibernate是一個(gè)開放源代碼的對(duì)象關(guān)系映射(ORM)框架,它對(duì)JDBC進(jìn)行了非常輕量級(jí)(相對(duì)于EJB這一套)的對(duì)象封裝,它將POJO(就是咱們的domain)與數(shù)據(jù)庫表建立映射關(guān)系,是一個(gè)全自動(dòng)的orm框架,Hibernate可以自動(dòng)生成SQL語句,自動(dòng)執(zhí)行,使得Java程序員可以隨心所欲的使用對(duì)象編程思維來操縱數(shù)據(jù)庫。
JPA是Sun官方提出的Java持久化規(guī)范。它為Java開發(fā)人員提供了一種對(duì)象/關(guān)系映射工具來管理Java應(yīng)用中的關(guān)系數(shù)據(jù)。他的出現(xiàn)主要是為了簡化現(xiàn)有的持久化開發(fā)工作和整合ORM技術(shù),結(jié)束現(xiàn)在Hibernate、TopLink(現(xiàn)在叫EclipseLink)等ORM框架各自為營的局面。
值得注意的是,JPA是在充分吸收了現(xiàn)有Hibernate、TopLink等ORM框架的基礎(chǔ)上發(fā)展而來的,具有易于使用、伸縮性強(qiáng)等優(yōu)點(diǎn)。
目標(biāo):
簡化現(xiàn)有Java EE和Java SE應(yīng)用的對(duì)象持久化的開發(fā)工作;
Sun希望整合ORM技術(shù),實(shí)現(xiàn)一統(tǒng)江湖。
簡單一句話:JPA是持久化規(guī)范,而Hibernate是其實(shí)現(xiàn)。
JPA的優(yōu)缺點(diǎn)
jdbc操作數(shù)據(jù)庫底層技術(shù)
? (1)轉(zhuǎn)換的時(shí)候特別麻煩 對(duì)象需要進(jìn)行封裝和拆分 比較麻煩
? (2)重復(fù)性代碼比較多
? ? (3)移植數(shù)據(jù)庫比較麻煩
? 操作數(shù)據(jù)庫的時(shí)候,如果使用jdbc,可能要寫兩套代碼
? (4)jdbc 自身沒有緩存(Cache),如果性能上面需要控制的化,就需要寫緩存代碼
? (5)jdbc不是面向?qū)ο蟮乃季S來操作的呀 面向sql操作,如果是sql高手,操作jdbc很爽的;
? (6)比較簡單 比較直接,就可以操作數(shù)據(jù)庫
? JPA的:
? (1)面向?qū)ο蟛僮鳎僮鲗?duì)象 就相當(dāng)于操作數(shù)據(jù) 比如? entityManager.perisit(employee)
? ? (2) 移植數(shù)據(jù)比較方法,以后如果想換數(shù)據(jù)庫,只需要換一個(gè)數(shù)據(jù)庫方言就OK
? ? (3)JPA有緩存,效率不錯(cuò)的 (一級(jí)緩存 二級(jí)緩存 查詢緩存)
? 缺點(diǎn):
? (1)不能干預(yù)sql的生成 ,查詢一個(gè)數(shù)據(jù) find? 默認(rèn)查詢所有字段 (select * from )
? (2)有些優(yōu)化 jpa做不了,比如特別大數(shù)據(jù)量的時(shí)候,jpa也不適合,mybatis也解決不了 (架構(gòu)策略 分庫 分表 (分布式))
? ? (3)一個(gè)項(xiàng)目里面 對(duì)sql要求比較高,就不適合jpa
?
JPA使用于中小型的項(xiàng)目
JPA CRUD
和以前學(xué)習(xí)JDBC一樣,咱們需要抽取一個(gè)工具類
public class JPAUtils {
//保證EntityManagerFactory是單例
??private static EntityManagerFactory entityManagerFactory;
??static {
????try {
//對(duì)應(yīng)配置文件里面的persistence-unit name="cn.itsource.jpa"
??????entityManagerFactory = Persistence.createEntityManagerFactory("cn.itsource.jpa");
????} catch (Exception e) {
??????e.printStackTrace();
throw new RuntimeException("解析配置文件或者映射配置出現(xiàn)異常:" + e.getMessage());
????}
??}
??public static EntityManager getEntityManager() {
????return entityManagerFactory.createEntityManager();
??}
}
導(dǎo)入依賴的jar包
persistence.xml的配置
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
? ? <!--
? ? ? ? 持久化單元名稱
? ? ? ? name :取一個(gè)單元的名稱
? ? ? ? transaction-type:事務(wù)類型 本地?cái)?shù)據(jù)庫的事務(wù)
? ? -->
? ? <persistence-unit name="cn.itsource.jpa" transaction-type="RESOURCE_LOCAL">
? ? ? ? <properties>
? ? ? ? ? ? <!-- 必須配置4個(gè)連接數(shù)據(jù)庫屬性 -->
? ? ? ? ? ? <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
? ? ? ? ? ? <property name="hibernate.connection.url" value="jdbc:mysql:///jpa" />
? ? ? ? ? ? <property name="hibernate.connection.username" value="root" />
? ? ? ? ? ? <property name="hibernate.connection.password" value="123456" />
? ? ? ? ? ? <!-- 必須配置1個(gè)方言屬性 -->
? ? ? ? ? ? <!-- 實(shí)現(xiàn)跨數(shù)據(jù)庫關(guān)鍵類 :查詢MySQLDialect的getLimitString方法 -->
? ? ? ? ? ? <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
? ? ? ? ? ? <!-- 可選配置 ddl數(shù)據(jù)定義語言(建庫建表建約束)
? ? ? ? ? ? ? ? ? ? ? ? ? dml數(shù)據(jù)操作語言 (insert update delete)
? ? ? ? ? ? ? ? ? ? ? ? ? dql 數(shù)據(jù)查詢語言(select)
? ? ? ? ? ? ? ? ? ? ? ? ? tcl 事務(wù)控制語言 (commit rollback)
? ? ? ? ? ? ? ? ? ? ? ? ? -->
? ? ? ? ? ? <!-- 是否自動(dòng)生成表 -->
? ? ? ? ? ? <property name="hibernate.hbm2ddl.auto" value="create" />
? ? ? ? ? ? <!-- 是否顯示sql -->
? ? ? ? ? ? <property name="hibernate.show_sql" value="true" />
? ? ? ? ? ? <!-- 格式化sql -->
? ? ? ? ? ? <!--<property name="hibernate.format_sql" value="true" />-->
? ? ? ? </properties>
? ? </persistence-unit>
</persistence>
每次都先添加數(shù)據(jù)
domain

add

update

查詢一條

查詢?nèi)?/h3>

刪除

建表策略
create 創(chuàng)建策略,先刪除 在創(chuàng)建
? ? ? ? ? ? ? ? ? update (測試)更新策略? 不會(huì)刪除? 如果發(fā)現(xiàn)沒有表,也會(huì)創(chuàng)建
? ? ? ? ? ? ? ? ? ? ? ? 如果是表里面新增的字段 ,配置都有效果
? ? ? ? ? ? ? ? ? ? ? ? 如果這個(gè)表里面已經(jīng)存在該字段 去修改屬性 沒有效果 比如length
? ? ? ? ? ? ? ? ? create-drop 先刪除 在創(chuàng)建 在刪除? 不怎么會(huì)用? 面試會(huì)問
? ? ? ? ? ? ? ? ? ? ? ? ? ? 把entityManagerFactory關(guān)閉
? ? ? ? ? ? ? ? ? ? ? ? 臨時(shí)表 臨時(shí)使用表 使用完之后,數(shù)據(jù)就不應(yīng)該存在
? ? ? ? ? ? ? ? ? validate 驗(yàn)證策略 當(dāng)前實(shí)體配置和數(shù)據(jù)庫的配置進(jìn)行對(duì)比驗(yàn)證
? ? ? ? ? ? ? ? ? ? ? ? ? ? 如果有對(duì)應(yīng)實(shí)體,但是沒有對(duì)應(yīng)的數(shù)據(jù)庫表 報(bào)錯(cuò)
? ? ? ? ? ? ? ? ? ? ? ? ? ? 數(shù)據(jù)庫多字段 OK
? ? ? ? ? ? ? ? ? ? ? ? ? ? 數(shù)據(jù)庫少字段 不OK
? ? ? ? ? ? ? ? ? 使用場景:比如已知數(shù)據(jù)庫的前提下 就可以把實(shí)體的配置和數(shù)據(jù)庫的配置進(jìn)行對(duì)比
如
