Java Persistence API:用于对象持久化的 API
Java EE 5.0 平台标准的 ORM 规范,使得应用程序以统一的方式访问持久层
1. JPA 概述
架构图:
JPA和Hibernate的关系:
JPA 是 hibernate 的一个抽象(就像JDBC和JDBC驱动的关系):
JPA 是规范:JPA 本质上就是一种 ORM 规范,不是ORM 框架 —— 因为 JPA 并未提供 ORM 实现,它只是制订了一些规范,提供了一些编程的 API 接口,但具体实现则由 ORM 厂商提供实现
Hibernate 是实现:Hibernate 除了作为 ORM 框架之外,它也是一种 JPA 实现
从功能上来说, JPA 是 Hibernate 功能的一个子集
JPA 的实现(JPA 供应商):
Hibernate:
JPA 的开发者就是 Hibernate 和 EJB 的开发者
Hibernate 从 3.2 开始兼容 JPAOpenJPA
OpenJPA 是 Apache 组织提供的开源项目TopLink
TopLink 以前需要收费,如今开源了,Oracle 公司的项目
JPA 的优势:
标准化: 提供相同的 API,这保证了基于JPA 开发的企业应用能够经过少量的修改就能够在不同的 JPA 框架下运行。
简单易用,集成方便: JPA 的主要目标之一就是提供更加简单的编程模型,在 JPA 框架下创建实体和创建 Java 类一样简单,只需要使用 javax.persistence.Entity 进行注释;JPA 的框架和接口也都非常简单。
可媲美JDBC的查询能力: JPA的查询语言是面向对象的,JPA定义了独特的JPQL,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。
支持面向对象的高级特性: JPA 中能够支持面向对象的高级特性,如类之间的继承、多态和类之间的复杂关系,最大限度的使用面向对象的模型
JPA 主要 3 技术(掌握)
ORM 映射元数据:JPA 支持 XML 和 JDK 5.0 注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中。
JPA 的 API:用来操作实体对象,执行CRUD操作,框架在后台完成所有的事情,开发者从繁琐的 JDBC和 SQL代码中解脱出来。
查询语言(JPQL):这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序和具体的 SQL 紧密耦合
2. JPA 持久化对象开发步骤:
2.1 导入 HIBERNATE JPA 实现(配置 POM 文件)
<dependencies>
<!--配置 HIBERNATE JPA 实现包 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.2.12.Final</version>
</dependency>
</dependencies>
2.2 创建 persistence.xml, 在这个文件中配置持久化单元
注意:persistence.xml 放置于 类路径下的 META-INF 目录下,persistence.xml 文件名称固定
- 需要配置连接数据库信息
- 需要指定 JPA 使用哪个持久化的框架以及配置该框架的基本属性
- 需要指定持久化的实体类
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">
<!--persistence-unit 定义持久化单元:
name 属性:定义持久化单元名称
transaction-type 属性:定义事务类型,此处为本地事务 RESOURCE_LOCAL-->
<persistence-unit name="helloJpa" transaction-type="RESOURCE_LOCAL">
<!-- provider 配置 实现 JPA 的 ORM 持久化框架-->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<!-- properties 定义连接数据库信息-->
<properties>
<!-- jpa中连接数据库 -->
<property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@192.168.0.112:1521:XE" />
<property name="javax.persistence.jdbc.user" value="ZHANGJIAN" />
<property name="javax.persistence.jdbc.password" value="zhangjian"></property>
<!-- jpa中配置hibernate基本属性 -->
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<!-- <property name="hibernate.hbm2ddl.auto" value="update" />-->
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
</properties>
</persistence-unit>
</persistence>
2.3 创建持久化实体类
package org.zj.jpa.demo.entity;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;
/**
* Created by ZhangJian on 2018/1/17.
*/
@Entity
@Table(name = "t_order")
public class OrderEntity {
@Id
@SequenceGenerator(name="seq_name",sequenceName = "order_seq",allocationSize = 1)
@GeneratedValue(generator = "seq_name")
private Long id;
private String description;
private BigDecimal totalMoney;
@Temporal(TemporalType.TIMESTAMP)
private Date createOrderTime;
private Integer state;
2.4 测试
package org.zj.jpa.demo.test;
import org.zj.jpa.demo.entity.OrderEntity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Date;
/**
* Created by ZhangJian on 2018/1/17.
*/
public class App {
public static void main(String[] args) {
// 创建 EntityManagerFactory 对象 类似于 Hibernate 中 sessionFactory 对象
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("helloJpa");
// 创建 EntityManager 对象 类似于 Hibernate 中的 Session 对象
EntityManager entityManager = entityManagerFactory.createEntityManager();
// 开启事务
entityManager.getTransaction().begin();
// 持久化实体操作
OrderEntity order = new OrderEntity();
order.setCreateOrderTime(new Timestamp(new Date().getTime()));
order.setDescription("田鸡又肚子疼");
order.setState(1);
order.setTotalMoney(new BigDecimal(2000));
entityManager.persist(order);
// 提交事务
entityManager.getTransaction().commit();
entityManager.close();
entityManagerFactory.close();
}
}
3.注解元数据介绍
/**
* Entity 注解: 定义该类为持久化类
* name 属性:定义数据库中的表名 跟 该持久化类进行关联,可以不配,默认关联的以实体类的类名对应的表。
* Table 注解: 如果数据库中没有表,使用该注解,定义自动创建表的时候的表名
*
* ID 注解 : 定义标识属性
* GeneratedValue 注解: 描述主键的生成的策略
* JPA 使用 GenerationType 该枚举类型定义了 4 种 生成策略:
* AUTO: 底层是否支持自增长或者序列
* IDENTITY:必须 数据库支持 自增长策略。 mysql
* SEQUENCE:支持序列的数据库,oracle :HIBERNATE_SEQ
* TABLE: hibernate 自动创建一个 Table 来保存主键值。
*
* SequenceGenerator 注解:定义创建序列的规则
*
*
* Column 注解: 定义对应的表的字段的名称,约束的规则(定义长度,唯一....),该注解可以不配,不配默认使用实体属性名称作为表的列名称
*
*
* Temporal 注解:定义表中日期的列采用具体的日期类型。
* JPA 使用 TemporalType 该枚举类型 定义了 3z 中 数据库日期类型:
* date:带年月日
* time:带时分秒
* TIMESTAMP:带年月日时分秒后面的更加精确的时间
*
* Transient 注解:指定修饰的属性,不作为表中的列。忽略该属性
*/
@Entity
@Table(name = "t_order")
public class OrderModel {
@Id
@GeneratedValue(generator = "order_seq")
@SequenceGenerator(name = "order_seq",sequenceName = "order_seq",allocationSize = 1)
private Long id;
private String description;
@Temporal(TemporalType.TIMESTAMP)
private Date createOrdTime;
private Integer state;
private Double totalMoney;
@Transient
private String noCreateColumn;
4. JPA 常用 API
Persistence:JPA 提供的一个获取 EntityManagerFactory 对象的工具类
Persistence.createEntityManagerFactory("helloJpa")EntityManagerFactory JPA 应用中只有一份,通过它创建 EntityManager 对象。
EntityManager 封装 CRUD 基本操作,管理 实体对象状态,一级缓存。
entityManager.persist(order):没有主键的返回值,该方法的执行也会把一个临时状态的 对象转为受容器管理的 持久化对象。只有在刷新容器或者事务提交的时候,才会发 insert 语句到 数据库。
entityManager.find(OrderModel.class, 1L):返回的是受容器管理的真实的类型的对象,立即加载。
entityManager.getReference(OrderModel.class,1l):返回的是受容器管理的真实的类型的对象,懒加载
更新操作方式1,使用快照更新:OrderModel orderModel = entityManager.find(OrderModel.class, 1L);
orderModel.setDescription("通过快照更新,没有显示的调用 meger方法");
更新操作方式2,meger: 传入参数对象如果是 DO 对象,执行完该方法然后是 DO 对象,但是方法执行后返回的是 PO 对象。merger 更新的 DO 对象会把更新的数据就会覆盖容器中已经存在的要修改的 PO 对象数据。merger 的参数对象是 TO ,就会执行 insert 操作。
entityManager.remove(orderModel):删除的参数对象为 PO 对象
entityManager.createQuery("from OrderModel "):创建 Quqery 接口,需要出入 JPQL 语句。Quqery 接口 API:
query.getResultList():查询记录使用 List 封装。
query.getSingleResult(): 查询当行记录
setFirstResult(0): 设置开始下标
setMaxResults(1):设置抓取记录条数
jpql 带参数的查询支持三种:请看hibernate*