JPA規範(java持久化API)JPA和Hibernate等框架一樣,都是java持久化解決方案,負責把數據保存到數據庫。不同的是,JPA只是一種標註,規範,而不是框架。JPA自己沒有具體的實現。
使用JPA後,程序不在依賴於某種ORM框架。如果原來用的JPA+Hibernate,則完全可以改爲使用JPA+TopLink,只需要修改配置即可。
JPA通過註解來配置實體類和數據庫的映射關係,下面來看一個具體的例子。
<span style="font-size:18px;">
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity//表示實體類可以被持久化
@Table(name = "tb_person")//指定該實體類對應的數據庫表
public class Person{
@Id//指定該列的主鍵
@GeneratedValue(strategy = GenerationType.AUTO)//主鍵類型,auto爲增長類型
private Integer id;
@Column(name = "name")//指定該屬性對應的數據庫列名
private String name;
@Column(name = "<span style="font-family: Arial, Helvetica, sans-serif;">age</span>")</span>
<span style="font-size:18px;"> private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}</span>
實體類用java註解來配置也相當的簡單。有一點需要注意的是實體類主鍵最好使用可以爲null的類型,例如Integer Long等
JPA的API
JPA的API都位於javax.persistence包下。
1 獲取EntityManager
<span style="font-size:18px;">public void init() throws ServletException {
if (emFactory == null) {
emFactory = Persistence.createEntityManagerFactory("jpa");
}
}</span>
參數jpa在persistence.xml中配置
<span style="font-size:18px;"> public void add(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
EntityManager em = emFactory.createEntityManager();
Person p<span style="font-family: Arial, Helvetica, sans-serif;">erson </span>= new Person();
person.setName("Person" + new Random().nextInt(10));
person.setAge(15 + new Random().nextInt(10));
em.getTransaction().begin();
em.persist(student);
em.getTransaction().commit();
em.close();
this.list(request, response);
}</span>
實體類的狀態
跟Hibernate一樣,JPA中的實體類也包括幾種狀態
jpa 實體生命週期有四種狀態
-
(臨時狀態)Transient:瞬時對象,尚未有id,還未和Persistence Context建立關聯的對象。
-
(持久化狀態)Persistent:持久化受管對象,有id值,已經和Persistence Context建立了關聯的對象。持久化狀態的對象可以執行任何有關數據庫的操作。
-
(分離狀態)Datached:遊離態離線對象,有id值,但沒有和Persistence Context建立關聯的對象。無法進行數據庫操作
-
Removed:刪除的對象,有id值,尚且和Persistence Context有關聯,但是已經準備好從數據庫中刪除
Managed狀態下的數據保存,更新以及刪除數據下的Removed狀態,數據都不會立即更新到數據庫,只有當你事務提交或者em.flush(),纔會立即更新到數據庫。
Datached的狀態,可以調用em.merge()方法,這個方法會根據實體類的id來更新數據庫數據,這時實體類變成了Managed狀態。
2 持久化persist()persist()將臨時狀態的對象保存進數據庫。因爲持久化時涉及數據庫的寫入,因此需要用到事物
<span style="font-size:18px;"> EntityManager em = emFactory.createEntityManager();
Student student = new Student();
student.setName("Student " + new Random().nextInt(10));
student.setAge(15 + new Random().nextInt(10));
em.getTransaction().begin();
em.persist(student);
em.getTransaction().commit();
em.close();</span>
3 查找find()與getReference()
find()與getReference()都能查找對象,不同的是當對象不存在時,find會返回空getReference會拋出javax.persistence.EntityNotFoundException異常
4 保存merge()
merge(Object obj)將修改後的對象保存進數據庫。merge時要用到事務。
<span style="font-size:18px;"> EntityManager em = emFactory.createEntityManager();
em.getTransaction().begin();//開啓事務</span>
<span style="font-size:18px;"></span><pre name="code" class="java"><span style="font-size:18px;"><span style="white-space:pre"> </span>Student student = em.find(Student.Class,1);//查詢</span>
student.setName("aa");em.merge(student);//保存修改em.getTransaction().commit();//提交事物em.close();
5 remove(object obj)將對象從數據庫中刪除,需要開啓事務
6 刷新refresh()和包含contains()
refresh(Object obj)從新從數據庫中讀取數據。contains(Object obj)判斷對象是否在數據庫返回true,false
7 查詢 creatQuery()
creatQuery()返回javax.persistence.Query對象。Query使用JPQL(java persistence query language)語句進行查詢,類似hibernate的HQL。
<span style="font-size:18px;">EntityManager em = emFactory.createEntityManager();
List studentList = em.createQuery(
" select s from Student s order by s.id desc ").setMaxResults(
100).getResultList();</span>
<span style="font-size:18px;"><span style="white-space:pre"> </span>em.close();</span>
8 寫入數據庫flush()
執行persist(),merge()時,數據不會立即寫入數據庫中,而是由JPA緩存起來,在進行flush()時寫入。在事務提交時,JPA會自動執行flush()一次性保存所有數據。如果需要將數據立即寫入數據庫,可以手動flush()。
9 清除對象 clear()
clear()清除所有被監視的(Session中的)實體類對象