JPA+Hibernate+Maven環境搭建
JPA(Java Persistence API)並不是一套持久層的框架,而是一套規範,它提倡以面向物件的方式來對物件進行持久化操作,而不是面向資料庫的方式持久化物件,開發人員不再需要編寫SQL語句來實現實體的持久化操作。基於JPA規範上去實現持久層,這才形成了一套持久層的框架(例如Hibernate、TopLink、JDO這些都是實現了JPA規範的的持久層框架)。也就是說,實現了JPA規範的持久層框架,那麼你可以用面向物件的方式去對java實體物件進行增刪改查的操作,而不用自己去編寫SQL。
需要學習JPA,首先需要把環境搭起來,這裡選擇實現JPA規範的持久層框架是Hibernate,版本為5.2.11.Final,並且採用maven進行依賴包的管理,具體步驟如下:
1、建立Maven專案,這一步比較簡單,可以直接在IDE建立。
2、新增hibernate-entitymanager依賴包:使用Hibernate來進行實體的管理,實現實體的CRUD操作,我們只需要引入這個hibernate-entitymanager依賴包即可,其它需要依賴的包將由maven自動引入,這樣我們就不用關係具體需要依賴哪些jar包了。當然,junit也是必不可少的。所以需要引入的jar包就兩個,簡單方便:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lzj.jpa</groupId>
<artifactId>jpa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging >
<name>jpa</name>
<url>http://maven.apache.org</url>
<properties>
<project.hibernate.version>5.2.11.Final</project.hibernate.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${project.hibernate.version}</version>
</dependency>
<!-- jdbc driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
3、JPA需要一個persistence.xml檔案,這個檔案可以定義持久化單元、資料庫連線資訊、事務屬性、持久化的提供者等。所謂的持久化單元,就是一堆實體類的集合,在該檔案內可以定義多個持久化單元,但是各個持久化單元的名稱必須唯一,不可重複。另外,JPA要求把persistence.xml原始碼目錄的META-INFO目錄下。persistence.xml內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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"
version="2.0">
<!-- 為持久化單元取名為jpa -->
<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="" value=""/>
<property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="mysqlAdmin" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpa?useUnicode=true&characterEncoding=UTF-8" />
</properties>
</persistence-unit>
</persistence>
在該檔案我們定義了一個名為persistenceUnit的持久化單元,同時定義了事務屬性,資料庫連線資訊以及持久層框架的一些屬性等,這裡簡單介紹一下幾個屬性:
(1)、transaction-type:定義事務的型別。事務型別分為本地事務和全域性事務。本地事務通常是在一個庫內實現的事務,由connection控制。而全域性事務是跨庫的事務。我們這裡只是操作單一的庫,所以選擇的是本地事務;
(2)、hibernate.dialect:使用的方言,這大家都知道,我這裡使用的是mysql資料庫,所以選擇mysql方言;
(3)、hibernate.hbm2ddl.auto:這裡可以定義持久層框架要如何更新資料庫表結構。前面已經說了,實現了JPA規範的持久層框架是面向物件的,所以不應該手動建立表或者更新表,而應該交由持久層框架實現。該配置項有以下幾個可配置值:
create-drop:每次載入實體操作工廠(hibernate是SessionFactory、JPA是EntityManagerFactory)時根據model類生成表,但是實體操作工廠一關閉,表就自動刪除;
update:第一次載入實體操作工廠時根據model類會自動建立起表的結構(前提是先建立好資料庫),以後載入實體操作工廠時根據model類自動更新表結構,即使表結構改變了但表中的行仍然存在不會刪除以前的行。當部署到伺服器後,表結構是不會被馬上建立起來的,是要等應用第一次執行起來後才會;
validate:每次載入實體操作工廠時,驗證建立資料庫表結構,只會和資料庫中的表進行比較,不會建立新表,但是會插入新值。
(4)、hibernate.show_sql:在操作實體的過程中是否需要在控制檯列印具體的SQL語句。true為列印,false不列印。
4、定義實體:在定義個實體時,可以通過很多的註解去維護與資料庫內表的對應資訊,當然也可以使用XML檔案去維護。我這裡是選擇使用註解去維護。比如我定義了一個Persion實體,內容如下:
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_persion")
public class Persion {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private Integer id;
@Column(name="s_name")
private String name;
@Column(name="i_age")
private Integer age;
/**
* 底層使用代理建立實體類,需要提供一個無參的建構函式
*/
public Persion(){}
public Persion(String name, Integer age){
this.name = name;
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;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
使用註解解釋如下:
@Entity:標註在類上,標識這是一個實體,表示需要交給持久層框架去實現該實體的持久化工作;
@Table:標註在類上,定義該實體與資料庫的哪個表對應,也就是定定義該實體對應的資料庫中的表名,具體名稱由該註解的name屬性指定;
@Id:標註在實體屬性上,標識該實體屬性是唯一標識,即主鍵;
@GeneratedValue:標註在實體屬性上,定義主鍵的生成策略,生成策略由由該註解的strategy屬性指定,具體生成策略有以下四個取值:
- GenerationType.AUTO:該策略不限制具體的生成策略,具體怎麼生成主鍵交由持久層框架是決定,比如如果mysql資料庫,可能採用自增方式生成主鍵;如果是Oracle資料庫可能採用序列的方式生成主鍵;
- GenerationType.IDENTITY:該策略採用欄位自增的方式生成主鍵,要求資料庫支援列自增功能;
- GenerationType.SEQUENCE:該策略採用序列的方式生成主鍵,要求資料庫支援序列功能;
- GenerationType.TABLE:使用表的方式生成主鍵,一般該表定義兩列,一列是表名,一列是主鍵值。效能較差。
@Column:標註在實體屬性上,定義該實體屬性對應資料庫表的哪個欄位,具體欄位名由該註解的name屬性指定
注意:由於持久層框架一般是採用反射機制操作實體類,所以一般需要提供一個無參的建構函式。
5、編寫測試類,程式碼如下:
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.junit.Test;
import junit.framework.TestCase;
public class PersionTest extends TestCase {
@Test
public void testPersion(){
EntityManagerFactory factory = Persistence.createEntityManagerFactory("persistenceUnit");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
em.persist(new Persion("lzj", 26));
em.getTransaction().commit();
em.close();
factory.close();
}
}
這裡需要說明三點:
(1)、在建立EntityManagerFactory(實體管理器工廠)的時候根據我們定義的持久化單元名稱去建立實體管理器工廠,在建立實體管理器工廠就已經實現了建立表、更新表的動作;
(2)、persist(Object):方法實現對應實體持久化到資料庫中,就是真正的插入操作,可開啟事務進行操作;
(3)、對應實體管理器、實體管理器工廠類需要在使用之後進行關閉資源;
經過以上幾個步驟,就實現了JPA+Hibernate+Maven環境的搭建,完成後的專案結構如下:
在執行測試類時候,應該能在資料庫看到相應的表和資料,同時,如果設定了列印具體sql屬性,那麼執行完之後可以在控制檯下看到列印的具體sql: