转自:https://blog.csdn.net/aspnetandjava/article/details/7034779

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&amp;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;

}

}

单元测试

    1. @Test public void save() {
    2. EntityManagerFactory factory = Persistence.createEntityManagerFactory(“itcast”);
    3. EntityManager em = factory.createEntityManager();
    4. em.getTransaction().begin();
    5. em.persist(new AirLine(“PEK”,”SHA’,”北京飞上海”));
    6. em.getTransaction().commit();
    7. em.close()
    8. factory.close();
    9. factory.close();
    10. }

3.JPA开发的更多相关文章

  1. JPA 开发中遇到的错误

    JPA 开发中遇到的错误 (2011-07-13 16:56:12) 转载▼ 标签: 杂谈 分类: Java/J2EE 常见异常1.异常信息:org.hibernate.hql.ast.QuerySy ...

  2. 转:使用 Spring Data JPA 简化 JPA 开发

    从一个简单的 JPA 示例开始 本文主要讲述 Spring Data JPA,但是为了不至于给 JPA 和 Spring 的初学者造成较大的学习曲线,我们首先从 JPA 开始,简单介绍一个 JPA 示 ...

  3. JPA学习---第二节:JPA开发环境和思想介绍

    一.下载相关 jar http://hibernate.org/orm/ 下载 hibernate ,解压 http://www.slf4j.org/download.html 下载 slf4j,解压 ...

  4. 使用 Spring Data JPA 简化 JPA 开发

    从一个简单的 JPA 示例开始 本文主要讲述 Spring Data JPA,但是为了不至于给 JPA 和 Spring 的初学者造成较大的学习曲线,我们首先从 JPA 开始,简单介绍一个 JPA 示 ...

  5. 二十、springboot之jpa开发@MappedSuperclass 注解说明

    @MappedSuperclass使用条件: 当我们进行开发项目时,我们经常会用到实体映射到数据库表的操作,此时我们经常会发现在我们需要映射的几个实体类中,有几个共同的属性,例如编号ID,创建者,创建 ...

  6. JPA学习---第三节:搭建JPA开发环境和全局事务介绍

    一.创建 Java 项目 1.导入所需的 jar 包: 2.创建 persistence.xml 文件, 代码如下: <?xml version="1.0" encoding ...

  7. JPA 开发写SQL时候遇见的困难点

    官方文档 https://docs.spring.io/spring-data/jpa/docs/1.11.16.RELEASE/reference/html/#repositories.specia ...

  8. 在使用SSH+JPA开发中,ajax使用ObjectMapper类从后台向前台传值

    使用ObjectMapper对象的writeValue方法 ObjectMapper objectMapper = new ObjectMapper(); objectMapper.writeValu ...

  9. Spring Data JPA开发中遇到的问题1:org.hibernate.hql.internal.ast.QuerySyntaxException: DispatchShift is not mapped

    org.hibernate.hql.internal.ast.QuerySyntaxException: T_D_SHIFT_DISPATCH is not mapped 错误原因: 没有映射到表,经 ...

随机推荐

  1. ECNUOJ 2615 会议安排

    会议安排 Time Limit:1000MS Memory Limit:65536KB Total Submit:451 Accepted:102 Description 科研人员与相关领域的国内外同 ...

  2. C++11之decltype

    使用场景 在C++中常常要用到非常长的变量名.假设已经有变量和你将使用的变量是一个类型.就可以使用decltypekeyword 来申明一样的类型变量. decltype原理      返回现有变量类 ...

  3. [Recompose] Configure Recompose to Build React Components from RxJS Streams

    Recompose provides helper functions to stream props using an Observable library of your choice into ...

  4. Qt中事件分发源码剖析

    Qt中事件分发源码剖析 Qt中事件传递顺序: 在一个应该程序中,会进入一个事件循环,接受系统产生的事件,而且进行分发,这些都是在exec中进行的. 以下举例说明: 1)首先看看以下一段演示样例代码: ...

  5. 13.ng-value

    转自:https://www.cnblogs.com/best/tag/Angular/ 绑定给定的表达式到input[select]或 input[radio]的值上 <input type= ...

  6. 用efibootmgr管理UEFI启动项,添加丢失的启动项

    UEFI用来替代传统BIOS引导操作系统,学会修改UEFI启动项也变得十分重要,UEFI全称为:“统一的可扩展固件接口”(Unified Extensible Firmware Interface), ...

  7. noip 2018 day1 T1 铺设道路 贪心

    Code: #include<cstdio> using namespace std; int main() { int last=0,ans=0; int n;scanf("% ...

  8. 10G安装DataGuard

    最后更新时间:2013年8月4日,星期日 ★ oracle 10G安装环境 数据库软件安装环境不详细描述,网上到处有这方面资料,下面只简单描述下. 也可参考官方文档: http://docs.orac ...

  9. C++ lambda表达式 (一)

    为什么要lambda函数 匿名函数是许多编程语言都支持的概念,有函数体,没有函数名.1958年,lisp首先采用匿名函数,匿名函数最常用的是作为回调函数的值.正因为有这样的需求,c++引入了lambd ...

  10. InnoDB引擎索引大观

    InnoDB是mysql处理OLTP(online transcation process)类型业务的存储引擎.为了加快数据查询速度.InnoDB引擎提供了丰富的索引实现. 1. 索引的分类 索引能够 ...