JPA入門

weixin_34293059發表於2018-08-21

JPA介紹
JPA全稱為Java Persistence API ,Java持久化API是Sun公司在Java EE 5規範中提出的Java持久化介面。JPA吸取了目前Java持久化技術的優點,旨在規範、簡化Java物件的持久化工作。使用JPA持久化物件,並不是依賴於某一個ORM框架。

JPA和Hibernate的關係
1.JPA 是規範:JPA 本質上就是一種 ORM 規範
2.Hibernate 是實現:Hibernate 除了作為 ORM 框架之外,它也是一種 JPA 實現

6217104-aeaf46f9de9ffb87.png
image.png

ORM對映檔案之前使用的是配置方式,這裡可以通過JPA規範,把ORM對映使用註解來替代。

Hibernate的註解方式(HibernateJPA)

JPA 的供應商
1.Hibernate
2.OpenJPA
3.TopLink

6217104-f596810958320ac0.png
image.png

JPA特點:
1.標準化:
2.簡單易用
3.媲美JDBC
4.支援物件導向

開發流程:
第一步:建立Web專案,匯入依賴
必須建立Web專案

同時放入jpa模板檔案

6217104-4571474af8ed8e07.png
image.png

第二步:配置JPA核心配置檔案
建立JPA的核心配置檔案

核心配置persistence.xml(名稱是固定的), 在這個檔案中配置持久化單元
1.JPA 規範要求目錄結構:在META-INF中

  2.需要指定 JPA 使用哪個持久化的框架以及配置該框架的基本屬性
    a)需要指定跟哪個資料庫進行互動;
    b)指定方言等擴充套件屬性
6217104-4b18d6ce1c173ff0.png
image.png
6217104-1d5a81b20ffbd4ac.png
image.png

配置檔案:
程式碼:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

<persistence-unit name="java1803" transaction-type="RESOURCE_LOCAL">
    <!-- 指定JPA的實現廠商 -->
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <!-- 註冊實體 -->
    <class>com.qf.pojo.JavaPhone</class>
    <!-- 配置HibernatePersistenceProvider對應的屬性 -->
    <properties>
        <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"></property>
        <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/qqhr?characterEncoding=utf-8"></property>
        <property name="hibernate.connection.username" value="root"></property>
        <property name="hibernate.connection.password" value=""></property>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL55Dialect"></property>
        <property name="hibernate.show_sql" value="true"></property>
        <property name="hibernate.format_sql" value="true"></property>
        <!-- 生成表 -->
        <property name="hibernate.hbm2ddl.auto" value="update"></property>
    </properties>
</persistence-unit>  

</persistence>

注意<class>節點位置:


6217104-1c6f391f2f85432f.png
image.png

第三步:建立實體類和對映的註解
建立實體類, 使用 annotation 來描述實體類跟資料庫表之間的對映關係.
JPA 基本註解:
1.@Entity 標註用於實體類宣告語句之前,指出該Java 類為實體類,將對映到指定的資料庫表。
2.@Table 對映表格
a)常和@Entity配合使用。
b)Name可選,表示表的名稱,預設表名和實體名一致。
3.@Id 對映生成主鍵:通常置於屬性宣告語句之前,也可置於屬性的getter方法之前。必須有,定義了對映到資料庫表的主鍵屬性
4.@GeneratedValue 用於標註主鍵的生成策略,通過 strategy 屬性指定。
(strategy=GenerationType.AUTO)主鍵策略:
a)IDENTITY:採用資料庫 ID自增長的方式來自增主鍵欄位
b)AUTO: JPA自動選擇合適的策略,是預設選項;
c)SEQUENCE:通過序列產生主鍵

  1. @Column 對映表格列 (可選):常用屬性是 name,用於設定對映資料庫表的列名。

表和類的關聯


6217104-9904c38186d4899e.png
image.png

@Entity //宣告當前類為hibernate對映到資料庫中的實體類
@Table(name="qf_user") //宣告在資料庫中自動生成的表名

行和物件的關聯
OID,在主鍵


6217104-a6b657f836795fe2.png
image.png

@Id //宣告此列為主鍵

欄位和屬性的關聯


6217104-63d1fd8c20967ba8.png
image.png

程式碼:
@Entity
@Table(name = "my_computer")
public class MyComputer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long comId;//主鍵策略
@Column(name = "com_name")
private String comName;// 屬性對映
@Column(name = "com_desc")
private String comDesc;

public Long getComId() {
return comId;
}

public void setComId(Long comId) {
this.comId = comId;
}

public String getComName() {
return comName;
}

public void setComName(String comName) {
this.comName = comName;
}

public String getComDesc() {
return comDesc;
}

public void setComDesc(String comDesc) {
this.comDesc = comDesc;
}
}

註冊實體別忘記:


6217104-8392947f0c865201.png
image.png

第四步:開發DAO測試
初始化表測試:

public void initTable(){
//載入配置,得到工廠
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myjpa");
entityManagerFactory.close();
}

觀察控制檯的輸出如下所示:

create table my_computer (
comId bigint not null auto_increment,
com_desc varchar(255),
com_name varchar(255),
primary key (comId)
) engine=InnoDB

是核心配置檔案中的持久化單元名稱


6217104-9d19f05d754a2997.png
image.png

新增測試:
public void addCom(){
//第一步:載入配置,得到工廠
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myjpa");
//第二步:得到實體管理物件
EntityManager entityManager = entityManagerFactory.createEntityManager();
//第三步:開啟事務
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
//第四步:運算元據
MyComputer pojo = new MyComputer();
pojo.setComName("聯想");
pojo.setComDesc("支援國產");
entityManager.persist(pojo);
//第五步:提交事務
transaction.commit();
//第六步:關閉連結
entityManager.close();
entityManagerFactory.close();
}

6217104-9f630c06e22930e0.png
image.png

完成CRUD(persist, find, merge, remove)

public class MyComputerDAO {

public void initTable(){
//載入配置,得到工廠
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myjpa");
entityManagerFactory.close();
}

public void addCom(){
//第一步:載入配置,得到工廠
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myjpa");
//第二步:得到實體管理物件
EntityManager entityManager = entityManagerFactory.createEntityManager();
//第三步:開啟事務
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
//第四步:運算元據
MyComputer pojo = new MyComputer();
pojo.setComName("聯想");
pojo.setComDesc("支援國產");
entityManager.persist(pojo);
//第五步:提交事務
transaction.commit();
//第六步:關閉連結
entityManager.close();
entityManagerFactory.close();
}

public void findById(Long cid){
EntityManager entityManager = JPAUtils.getEntityManager();
MyComputer myComputer = entityManager.find(MyComputer.class, cid);
System.out.println(myComputer.getComName()+"\t"+myComputer.getComDesc());
entityManager.close();
}

public void updateCom(){
EntityManager entityManager = JPAUtils.getEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();

  MyComputer myComputer = entityManager.find(MyComputer.class, 1L);
  myComputer.setComDesc("中國夢");
  entityManager.merge(myComputer);

  transaction.commit();
  entityManager.close();

}

public void del(){
EntityManager entityManager = JPAUtils.getEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
MyComputer myComputer = entityManager.find(MyComputer.class, 1L);
entityManager.remove(myComputer);
transaction.commit();
entityManager.close();
}

public static void main(String[] args) {
MyComputerDAO dao = new MyComputerDAO();
// dao.initTable();
// dao.addCom();
// dao.findById(1L);
// dao.updateCom();
dao.del();
}

}
可以將上面重複的程式碼抽象成單例的工具類

注意:刪除必須在同樣一個實體管理物件中才可以,一個entityManager查,一個新entityManager刪除會失敗。

測試:


6217104-1a2dd30281aaf76f.png
image.png
6217104-cd3952c33fe62eb5.png
image.png

跨Session不在同樣一個事務中。
bug:


6217104-1a53d3abf53d8fce.png
image.png

相關文章