理論的東西如果不實踐,永遠不會變成自己的東西。本文將介紹用maven管理,用Hibernate作為JPA供應商,使用MYSQL數據庫,配置和使用JPA。
以下代碼已經上傳至GITHUB。
首先在pom.xml文件中添加依賴:
<dependencies>
<!-- 向pom添加必要依賴項 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- 將Hibernate用作jpa提供程序 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.1.Final</version>
</dependency>
<!-- 使用mysql數據庫,需要mysql驅動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.31</version>
</dependency>
</dependencies>
配置persistence.xml:
<?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="myJPA" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.domain.User</class>
<properties>
<!-- 配置Hibernate方言 -->
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<!-- 配置數據庫驅動 -->
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<!-- 配置數據庫用戶名 -->
<property name="hibernate.connection.username" value="root" />
<!-- 配置數據庫密碼 -->
<property name="hibernate.connection.password" value="000" />
<!-- 配置數據庫url -->
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpa?useUnicode=true&characterEncoding=UTF-8" />
<!-- 設置外連接抓取樹的最大深度 -->
<property name="hibernate.max_fetch_depth" value="3" />
<!-- 自動輸出schema創建DDL語句 -->
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="javax.persistence.validation.mode" value="none"/>
</properties>
</persistence-unit>
</persistence>
注意該persistence.xml要放在META-INF目錄下,persistence.xml是JPA配置的主要入口,當然後面在結合spring後,可以不用persistence.xml文件。
JPA有兩種事務模式:一種是RESOURCE_LOCAL,另外一種是JTA。關於事務,本人還不太了解,待我深入了解一番後,回來填坑/**
*
* <p>ClassName: Driver.java<p>
* <p>駕駛員實體類<p>
* @author linzj
* @createTime 2016年3月17日 上午10:07:57
*/
@Entity
@Table(name="driver")
public class Driver {
@Id
@GeneratedValue
private Long id;
@Column(name = "firstname")
private String firstName;
@Column(name = "lastname")
private String lastName;
@OneToMany(cascade=CascadeType.ALL)//傳播性持久化
@JoinColumn(name = "dirver_id")
private Set<Car> cars = new HashSet<Car>();
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Set<Car> getCars() {
return cars;
}
public void setCars(Set<Car> cars) {
this.cars = cars;
}
@Override
public String toString() {
return "Driver [id=" + id + ", firstName=" + firstName + ", lastName="
+ lastName + ", cars=" + cars + "]";
}
}
/**
*
* <p>ClassName: Car.java<p>
* <p>汽車類<p>
* @author linzj
* @createTime 2016年3月17日 上午9:35:01
*/
@Entity
@Table(name="car")
public class Car {
@Id
@GeneratedValue
private Long id;
@Column(name = "name")
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Car [id=" + id + ", name=" + name + "]";
}
}
上面注釋了cascade=CascadeType.ALL為傳播性持久化,顧名思義,就是在將一個Dirver對象持久化的同時,程序會同時給driver對象裡的car對象也進行持久化。
創建測試類:
/**
* 創建實體管理工廠類,並測試工廠是否為開啟狀態
*/
@Test
public void openTest(){
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJPA");
System.out.println("工廠類是否為開啟狀態:" + entityManagerFactory.isOpen());
}
/**
* 創建實例,並進行持久化測試
*/
@Test
public void addTest(){
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJPA");
// 創建實體管理對象
EntityManager entityManager = entityManagerFactory.createEntityManager();
// 創建一個新事務,記得開啟事務
EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
// 創建一個Driver對象和兩輛Car對象
Driver driver = new Driver();
driver.setFirstName("taylor");
driver.setLastName("swift");
Car carOne = new Car();
carOne.setName("BMW");
Car carTwo = new Car();
carTwo.setName("AUDI");
// 將car添加到driver集合中,並用EntityManager進行持久化
driver.getCars().add(carOne);
driver.getCars().add(carTwo);
entityManager.persist(driver);
// 提交事務,關閉EntityManager
entityTransaction.commit();
entityManager.close();
}
/**
* 使用JPA查詢實體
*/
@Test
public void findTest(){
EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJPA");
EntityManager em = emf.createEntityManager();
EntityTransaction et = em.getTransaction();
et.begin();
Driver driver = em.find(Driver.class, 1L);
Car car = em.getReference(Car.class, 2L);
driver.setFirstName("justin");
em.remove(car);
et.commit();
em.close();
}
JPA提供兩種不同的查詢方法,find()和getReference(),find方法將導致實體被獲取並且立即返回,如果數據庫中沒有數據,則返回空值。getReference並不是直接訪問數據庫???再深入了解,getReference在數據庫記錄不存在時,將拋出異常。
JPA的傳播性持久化,在對於使用EntityManager實例加載的實體上所完成的操作,JPA會進行跟蹤,被更改的實體將被標記為“髒數據”,該過程稱為“自動髒數據檢查”。在實體上完成的操作會導致更新語句,當開發人員提交事務時,JPA會執行這些更新語句。只要實體與EntityManager相連接,並且EntityManager保持打開狀態,那麼實體就會被跟蹤。當關閉EntityManager時,加載的實體將會分離(實體處於游離狀態),他們的狀態更改不會被跟蹤。此時需要一個新的EntityManager實例使用merge操作重新加載或者重新關聯實體。
以上就是JPA配置和使用的記錄,下一篇記錄下通過Spring使用JPA進行數據訪問。