JPA全称Java Persistence API,即Java持久化API,它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据,结合其他ORM的使用(如Hibernate),能达到简化开发流程的目的,使开发者能够专注于实现自己的业务逻辑上。目前比较成熟的 JPA 框架主要包括 Jboss 的 Hibernate EntityManager、Oracle 捐献给 Eclipse 社区的 EclipseLink、Apache 的 OpenJPA 等。本文中使用EclipseLink Jpa配置实现
一、创建新数据库连接
在MyEclipse中,点击Window—>Open Perspective,选择MyEclipse Database Explorer,创建一个新的数据库连接,如图所示,本文所用是MySQL数据库。
二、创建一个示例项目
1、右击项目—>MyEclipse—>Add Jpa Capabilities,添加EclipseLink,点击下一步,如图:
2、选择刚刚创建的数据库连接,如图所示:
3、点击完成后,会自动默认在src的META-INF中生成persistence.xml持久化文件(路径不需要修改),且persistence.xml内容如下。其中,<class></class>中内容是后面通过JPA逆向工程自动添加进的实体类,此处可暂时忽略。
<?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="springjersyjpa"
transaction-type="RESOURCE_LOCAL">
<provider>
org.eclipse.persistence.jpa.PersistenceProvider
</provider>
<class>com.spring.jersy.jpa.hibernate.model.Country</class>
<class>com.spring.jersy.jpa.hibernate.model.Province</class>
<class>com.spring.jersy.jpa.hibernate.model.User</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="root" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test" />
<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.persistence-context.flush-mode"
value="COMMIT" />
</properties>
</persistence-unit>
</persistence>
三、JPA逆向工程
MyEclipse提供了JPA逆向工程,能够将数据库中的表、字段等信息自动生成实体类并注解一一对应。具体流程如下:
1、进入MyEclipse Database Explorer,打开刚刚创建的“com.jdbc.mysql.Driver”连接,选择测试数据库“test”。
2、选择要逆向生成的表,右击选择“JPA Reverse Engineering”。弹出如图:
3、生成的实体类如下所示:
package com.spring.jersy.jpa.hibernate.model;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* Country entity. @author MyEclipse Persistence Tools
*/
@Entity
@Table(name = "country", catalog = "test")
public class Country implements java.io.Serializable {
// Fields
private Integer cid;
private String cname;
private Set<Province> provinces = new HashSet<Province>(0);
// Constructors
/** default constructor */
public Country() {
}
/** minimal constructor */
public Country(String cname) {
this.cname = cname;
}
/** full constructor */
public Country(String cname, Set<Province> provinces) {
this.cname = cname;
this.provinces = provinces;
}
// Property accessors
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "cId", unique = true, nullable = false)
public Integer getCid() {
return this.cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
@Column(name = "cName", nullable = false, length = 32)
public String getCname() {
return this.cname;
}
public void setCname(String cname) {
this.cname = cname;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "country")
public Set<Province> getProvinces() {
return this.provinces;
}
public void setProvinces(Set<Province> provinces) {
this.provinces = provinces;
}
}package com.spring.jersy.jpa.hibernate.model;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import static javax.persistence.GenerationType.IDENTITY;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.Table;/** * Province entity. @author MyEclipse Persistence Tools */@Entity@Table(name = "province", catalog = "test")public class Province implements java.io.Serializable { // Fields private Short id; private Country country; private String proName; // Constructors /** default constructor */ public Province() { } /** full constructor */ public Province(Country country, String proName) { this.country = country; this.proName = proName; } // Property accessors @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "id", unique = true, nullable = false) public Short getId() { return this.id; } public void setId(Short id) { this.id = id; } @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "cId", nullable = false) public Country getCountry() { return this.country; } public void setCountry(Country country) { this.country = country; } @Column(name = "proName", nullable = false, length = 32) public String getProName() { return this.proName; } public void setProName(String proName) { this.proName = proName; }}
四、JPA测试
JPA与Hibernate很相似,Hibernate依赖SessionFactory—>Session,JPA依赖EntityManagerFactory—>EntityManager实现各种操作。测试案例如下:
package com.spring.jersy.jpa.hibernate.test;
import java.util.Iterator;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import com.spring.jersy.jpa.hibernate.model.Country;
public class JpaTest {
private static EntityManagerFactory entityFactory = Persistence
.createEntityManagerFactory("springjersyjpa");
public static void main(String agrs[]) {
queryProvinceInnerJoinCountry();
}
/**
* 内连接多表关联查询
*/
public static void queryProvinceInnerJoinCountry() {
EntityManager em = entityFactory.createEntityManager();
// JPA中JPQL查询,必须为每个table定义别名
//字段名要和实体类中属性相对应
String jql = "select p.proName,c.cname from Province p inner join p.country c ";
Query query = em.createQuery(jql);
List<Object> list = query.getResultList();
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
Object[] obj = (Object[]) iterator.next();
System.out.println(obj[0]+" "+obj[1]);
}
em.close();
entityFactory.close();
}
/**
* 查询所有国家
*/
public static void findCountryAll() {
EntityManager em = entityFactory.createEntityManager();
// JPA中JPQL查询,必须为每个table定义别名
//字段名要和实体类中属性相对应
Query query = em.createQuery("select c.cId, c.cname from Country c ");
List<Object> list = query.getResultList();
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
Object[] obj = (Object[]) iterator.next();
System.out.println(obj[1]);
}
em.close();
entityFactory.close();
}
/**
* 根据国家编号查询国家名称
*
* @param id
*/
public static void queryCountryBycId(Integer id) {
EntityManager em = entityFactory.createEntityManager();
// JPA中JPQL查询,必须为每个table定义别名
//字段名要和实体类中属性相对应
Query query = em
.createQuery("select c.cname from Country c where c.cId = :id",
String.class);
String name = (String) query.setParameter("id", id).getSingleResult();
System.out.println(name);
em.close();
entityFactory.close();
}
/**
* 修改信息
*/
public static void updateCountry() {
EntityManager em = entityFactory.createEntityManager();
//打开事务
em.getTransaction().begin();
Country country = em.find(Country.class, 2);
country.setCname("英国");
em.persist(country);
//事务提交
em.getTransaction().commit();
em.close();
entityFactory.close();
}
/**
* 添加信息
*/
public static void saveCountry() {
EntityManager em = entityFactory.createEntityManager();
em.getTransaction().begin();
Country country = new Country();
country.setCname("中国");
em.persist(country);
em.getTransaction().commit();
em.close();
entityFactory.close();
}
}JPA支持JQL SQL语法,与Hibernate的HQL语法很近,但是也有很多不同的地方,如:JQL中实体类代表相应的表时,必须取别名(alias)等。