1. 什么是JPA
1. JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate、TopLink、JDO等ORM框架各自为营的局面。值得注意的是,JPA是在充分吸收了现有Hibernate、TopLink、JDO等ORM框架的基础上发展而来的,具有易于使用、伸缩性强等优点。从目前的开发社区的反应上看,JPA受到了极大的支持和赞扬,其中就包括了Spring与EJB3.0的开发团队。着眼未来几年的技术走向,JPA作为ORM领域标准化整合者的目标应该不难实现。
2. JPA的总体思想和现有Hibernate、TopLink、JDO等ORM框架大体一致,总的来说,JPA包括以下3方面的技术:
2.1 ORM映射元数据
JPA支持XML和JDK5.0注释(注解)两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中。
2.2 Java持久化API
用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发者可以从繁琐的JDBC和SQL代码中解脱出来。
2.3 查询语言
这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
提示:JPA不是一种新的ORM框架,他的出现只是用于规范现有的ORM技术,它不能取代现有的Hibernate、TopLink等ORM框架。相反,在采用JPA开发时,我们仍将使用这些ORM框架,只是此时开发出来的应用不再依赖于某个持久化提供商。应用可以在不修改代码的情况下在任何JPA环境下运行,真正做到低耦合,可扩展的程序设计。
2. 开发JPA依赖的jar文件
Hibernate核心包(8个文件)
hibernate-distribution-3.3.1.GA
hibernate3.jar
lib\bytecode\cglib\hibernate-cglib-repack-2.1_3.jar
lib\required\*.jar
Hibernate注解包(3个文件):hibernate-annotations-3.4.0.GA
hibernate-annotations.jar
lib\ejb3-persistence.jar、hibernate-commons-annotations.jar
Hibernate针对JPA的实现包(3个文件):hibernate-entitymanager-3.4.0.GA
hibernate-entitymanager.jar
lib\test\log4j.jar、slf4j-log4j12.jar
3.JPA的配置文件
JPA规范要求在类路径的META-INF目录下放置persistence.xml, 文件的名称是固定的,配置模板如下:
<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_1_0.xsd"
?? version="1.0">
?? <persistence-unit name="itcast" transaction-type=”RESOURCE-LOCAL”>
????? <properties>
???????? <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
???????? <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=”root” />
???????? <property name=”hibernate.connection.url”
?value=”jdbc:mysql://localhost:3306/itcast?useUnicode=true&characterEncoding=UTF-8”/>
???????? <property name=”hibernate.max_fetch-depth” value=”3” />
???????? <property name="hibernate.hbm2ddl.auto" value="update"/>
????? </properties>
?? </persistence-unit>
</persistence>
4. JPA实例
建立一个名为JPA的java project, 在src目录下新建META-INF文件夹,并把persistence.xml文件放入其中
建立实体bean
package cn.itcast.bean;
import javax.persistence.Entity;
import javax.persistentce.GeneratedValue;
import javax.persistentce.GeneratedType;
import javax.persistentce.Id;
?
@Entity
@Table(name=”xxx”)
public class Person {
private Integer id;
private String name;
private Date birthday; //1887-12-10
private Gender gerder = Gender.MAN;
private String info;? //存放大文本数据
private Byte[] file;?? //大数据(大于1M)延迟加载
private String imagepath;? //不希望该字段映射到数据库
?
public Person(String name) {
??? this.name = name;
}
?
@Id @GeneratedValue
public Integer getId() {
??????? return id;
}
public void setId(Integer id) {
??? this.id = id;
}
@Column(length=10,nullable=false,name=”personName”)
public String getName() {
??? return name;
}
public void setName(String name) {
??? this.name = name;
}
@Temporal(TemporalType.DATE)
public Date getBirthday() {
??? return birthday;
}
public void setBirthday(Date birthday) {
??? this.birthday = birthday;
}
@Enumerated(EnumType.STRING)
@Column(length=5,nullable=false)
public Gender getGender() {
??? return gender;
}
public vod setGender(Gender gender) {
??? this.gender = gender;
}
@Lob
public String getInfo {
??? return info;
}
public void setInfo(String info) {
??? this.info = info;
}
@Lob @Basic(fetch=FetchType.LAZY)
public Byte[] getFile() {
??? return file;
}
public void setFile(Byte[] file) {
??? this.file = file;
}
@Transient
publc String getImagepath() {
??? return imagepath;
}
public void setImagepath(String imagepath) {
??? this.imagepath = imagepath;
}
}
枚举类
package cn.itcast.bean;
public enum Gender {
??? MAM,WOMEN
}
?
测试代码
package junit.test;
?
public class PersonTest {
?
@Test public void save() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
??? em.getTransaction().begin();?? //开始事务
??? em.persist(new Persion(“传智博客”));?? //new状态
??? em.getTransaction().commit();
??? em.close();
??? factory.close();
}
@Test public void getPerson() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
??? Person person = em.find(Person.class,1);
??? System.out.println(person.getName());
??? em.close();
??? factory.close();
}
@Test public void getPerson() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
??? Person person = em.getReference(Person.class,1);
??? System.out.println(person.getName());
??? em.close();
??? factory.close();
}
?
@Test public void updatePerson() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
??? em.getTransaction().begin();?? //开始事务
??? Person person = em.find(Person.class,1);? //托管状态
??? person.setName (“老张”);? //处于托管状态,对person的修改可以同步到数据库
??? //em.clear();? //把实体管理器的所有实体变成游离状态
??? em.getTransaction().commit();
??? em.close();
??? factory.close();
}
@Test public void updatePerson2() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
??? em.getTransaction().begin();?? //开始事务
??? em.clear();? //把实体管理器的所有实体变成游离状态
??? person.setName (“老黎”);? //处于托管状态,对person的修改可以同步到数据库
??? em.merge(person);
??? em.getTransaction().commit();
??? em.close();
??? factory.close();
}
@Test public void delete() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
??? em.getTransaction().begin();?? //开始事务
??? Person person = em.find(Person.class,1);
?? ?em.remove(person);
??? em.getTransaction().commit();
??? em.close();
??? factory.close();
}
@Test public void query() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
?? ?????Query query = em.createQuery(“select o from Person o where o.id=?1”);
??????? query.setParameter(1,2);
??????? List<Person> persons = query.getResultList();
??????? for(Person person:persons)
??????????? System.out.println(person.getName());
??? em.close();
??? factory.close();
}
@Test public void deletequery() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
?? ?em.getTransaction().begin();
??????? Query query = em.createQuery(“delete from Person o where o.id=?1”);
??????? query.setParameter(1,2);
??????? query.executeUpdate();
??? em.getTransaction().commit();
??? em.close();
??? factory.close();
}
?
@Test public void queryupdate() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
?? ?em.getTransaction().begin();?? //开始事务
??? Query query = em.createQuery(“update Person o set o.name=:name where o.id=:id”);
??? query.setParameter(“name”,”xxx”);
??? query.setParameter(“id”,3);
??? query.executeUpdate();
??? em.getTransaction().commit();
??? em.close();
??? factory.close();
}
}
5. JPA中的一对多双向关联与级联操作
多的一方为关系维护端,关系维护端负责外键记录的更新,关系被维护端是没有权利更新外键记录
package cn.itcast.bean;
import javax.persistence.Entity;
@Entity
public class OrderItem {
private Integer id;
private String productName;
private Float sellPrice = 0f;
private Order order;
?
@Id @GeneratedValue
public Integer getId() {
??? return id;
}
public setId(Integer id) {
??? this.id = id;
}
@Column(length=40,nullable=false)
public String getProductName() {
??? return productName;
}
public void setProductName(String productName) {
??? this.productName = productName;
}
@Column(nullable=false)
public Float getSellPrice() {
??? return sellPrice;
}
public void setSellPrice (Float sellPrice) {
??? this. sellPrice = sellPrice
}
@ManyToOne(cascade={ascadeType.MERGE, CascadeType.REFERSH},optional=false)
@JoinColumn(name=”order_id”)
public Order getOrder() { //默认立即加载
??? return order;
}
public void setOrder(Order order) {
?? this.order = order;
}
}
Order实体
?
@Entity
@Table(name=”orders”)
public class Order {
private String orderid;
private Float amount = 0f;
private Set<OrderItem> items = new HashSet<OrderItem>();
?
@Id @Column(length=12)
public String getOrderid() {
??? return ordered;
}
public void setOrderid(String ordered) {
??? this.orderid = ordered;
}
@Column(nullable=false)
public Float getAmount() {
??? return amount;
}
public void setAmount(Float amount) {
??? this.amount = amount;
}
@OneToMany(cascade={CascadeType.REFRESH,CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REMOVE},fetch=FetchType.LAZY,mappedBy=”order”)
public Set<OrderItem> getItems() {? //默认延迟加载
??? return items;
}
public void setItems(Set<OrderItem> items) {
??? this.items = items;
}
保存操作
public class OneToManyTest {
?@Test public void save() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
??? em.getTransaction().begin();?? //开始事务
?
??? Order order = new Order();
??? order.setAmout(34f);
??? order.setOrderid(“999”);
??? OrderItem orderItem1 = new OrderItem();
??? orderItem1.setProductName(“足球”);
??? orderItem1.setSellPrice(90f);
??? OrderItem orderItem2 = new OrderItem();
??? orderItem1.setProductName(“瑜伽球”);
??? orderItem1.setSellPrice(30f);
??? order.addOrderItem(orderItem1);
??? order.addOrderItem(orderItem2);
?
??? em.persist(order);
??? em.getTransaction().commit();
??? em.close();
??? factory.close();
}
}
6. JPA中一对一双向关联
Peron实体
@Entity
public class Person {
private Integer id;
private String name;
private IDCard idcard;
public Person(){}
public Public(String name) { this.name = name }
@Id @GeneratedValue
public Integer getId() {
??? return id;
}
public void setId(Integer id) {
??? this.id = id;
}
public String getName() {
??? return name;
}
pubic void setName() {
??? this.name = name;
}
@OneToOne(optional=false,cascade=CascadeType.ALL)
@JoinColumn(name=”idcard_id”)
public IDCard getIdcard() {
??? return idcard;
}
public void setIdcard(IDCard idcard) {
??? this.idcard = idcard;
}
}
?
IDCard实体
public class IDCard {
private Integer id;
private String cardno;
private Persion person;
public IDCard (){}
public IDCard (String cardno) { this.cardno = cardno; }
?
@Id @GeneratedValue
public Integer getId() {
??? return id;
}
pubic void setId(Integer id) {
??? this.id = id;
}
@Column(length=18,nullable=false)
public String getCardno() {
??? return name;
}
public void setName(String name) {
??? this.name = name;
}
@OneToOne(mappedBy=”idcard”,cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH},optional=”false”)
public Person getPerson() {
??? return person;
}
pubic void setPerson(Person person) {
??? this.person = person;
}
}
保存操作
public class OneToManyTest {
?@Test public void save() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
??? em.getTransaction().begin();?? //开始事务
???
??? Person person = new Person(“老张”);
??? IDCard idcard = new IDCard(“11111”);
?
??? em.persist(person);
??? em.getTransaction().commit();
??? em.close();
??? factory.close();
}
}
7. JPA中多对多双向关联
public class Student {
private Integer id;
private String name;
private Set<Teacher> teachers= new HashSet<Teacher>();
public Student() {}
public Student(String name) { this name = name; }
@Id @GeneratedValue
public Integer getId() {…}
public void setId(Integer id) {…}
@Column(length=10,nullable=false)
public String getName() {…}
public void setId(String name){…}
@ManyToMany(cascade=CascadeType.REFRESH)
@JoinTable(name=”student_teacher”,inverseJoinColumns=@JoinColumn(name=”teacher_id”),joinColumns=@JoinColumn(name=”student_id”))
public Set<Teacher> getTeacher() {…}
public void setTeacher(Set<Teacher> teacher) {…}
}
Teacher实体
@Entity
public class Teacher
private Integer id;
private String name;
private Set<Student> student = new HashSet< Student >();
public Teacher() {}
public Teacher(String name) { this.name = name; }
@Id @GeneratedValue
public Integer getId() {…}
public void setId(Integer id) {…}
public String getName() {…}
public void setId(String name){…}
@ManyToMany(cascade=CascadeType.REFRESH,mappendBy=”teachers”)
public Set< Student> get Student () {…}
public void setTeacher(Set<Student> student) {…}
}
保存操作
public class ManyToManyTest {
?@Test public void save() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
??? em.getTransaction().begin();
??? em.persist(new Student(“小张”);
??? em.persist(new Teacher(“李勇”);
??? em.getTransaction().commit();
??? factory.close();
}
//建立学生跟老师的关系
@Test public void buildTS() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
??? em.getTransaction().begin();
??? Student student = em.find(Student.class,1);
??? student.addTeacher(em.getReference(Teacher.class,1));
??? em.getTransaction().commit();
??? em.close():
??? factory.close();
??? factory.close();
}
//解除学生跟老师的关系
@Test public void deleteTS() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
??? em.getTransaction().begin();
??? Student student = em.find(Student.class,1);
??? student.removeTeacher(em.getReference(Teacher.class,1));
??? em.getTransaction().commit();
??? em.close()
??? factory.close();
??? factory.close();
}
//删除老师
@Test public void deleteTeacher() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
??? em.getTransaction().begin();
? ??Student student = em.find(Student.class,1);
??? student.removeTeacher(em.getReference(Teacher.class,1));
??? em.remove(teacher);
??? em.getTransaction().commit();
??? em.close()
??? factory.close();
??? factory.close();
}
//删除学生
@Test public void deleteStudent() {
??? EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
??? em.getTransaction().begin();
??? Student student = em.getReference(Student.class,1);
??????? em.remove(student);
??? em.getTransaction().commit();
??? em.close()
??? factory.close();
??? factory.close();
}
?
}
8. 联合主键
@Embeddable
public class AirLinePK implements Serializable {
private String startCity;
private String endCity;
?
@Column(length=3)
public String getStartCity() {
??? return startCity;
}
public void setStartCity(String startCity) {
??? this.startCity = startCity;
}
@Column(length=3)
public String getEndCity() {
??? return endCity;
}
public void setEndCity(String endCity) {
??? this. endCity = endCity;
}
?
public int hashCode() {
??? final int prime = 31;
??? int result = 1;
??? result = prime * result + ((endCity ==null)?0:endCity.hashCode());
??? result = prime * result + ((startCity == null)?0:startCity.hashCode());
??? return result;
}
public boolean equals(Object obj) {
??? if(this == obj) return true;
??? if(obj == null) return false;
??? if(getClass() != obj.getClass()) return false;
??? final AirLinePK other = (AirLinePK) obj;
??? if(endCity == null) {
??????? if(other.endCity != null) return false;
???? }else if(!endCity.equals(other.endCity)) {
???????? return false;
???? }
???? if(startCity == null) {
??????? if(other. startCity != null) return false;
???? }else if(!estartCity.equals(other. startCity)) {
???????? return false;
???? }
??? return true;
}
}
AirLine实体
@Entity
public class AirLine {
private AirLinePK id;
private String name;
public AirLine() {}
public AirLine(AirLinePK id) {
?? this.id = id;
}
public AirLine(String startCity,String endCity,String name) {
??? this.id = new AirLinePk(startCity,endCity);
??? this.name = name;
}
@EmbeddedId
public AirLinePK getId() {
??? return id;
}
public void setId(AirLinePK id) {
??? this.id = id;
}
@Column(length=20)
public String getName() {
??? return name;
}
public void setName(String name) {
??? this.name = name;
}
}
单元测试
@Test public void save() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
??? EntityManager em = factory.createEntityManager();
??? em.getTransaction().begin();
??? em.persist(new AirLine(“PEK”,”SHA’,”北京飞上海”));
??? em.getTransaction().commit();
??? em.close()
??? factory.close();
??? factory.close();
?
}
?